From 90386e480f703786af00ff82faed5b75f967b501 Mon Sep 17 00:00:00 2001 From: Mark Musante Date: Tue, 16 Jun 2026 16:06:11 -0400 Subject: [PATCH 1/5] Ask UK compliance questions --- .../lib/IFComp/Controller/Admin/Questions.pm | 99 ++++++++++++++ IFComp/lib/IFComp/Controller/Entry.pm | 26 +++- IFComp/lib/IFComp/Schema/Result/Entry.pm | 19 ++- .../lib/IFComp/Schema/Result/EntryAnswer.pm | 124 ++++++++++++++++++ IFComp/lib/IFComp/Schema/Result/Question.pm | 101 ++++++++++++++ IFComp/root/src/admin/index.tt | 1 + IFComp/root/src/admin/questions/index.tt | 79 +++++++++++ IFComp/root/src/entry/_form.tt | 32 +++++ IFComp/t/controller_Admin-Questions.t | 10 ++ IFComp/t/lib/IFCompTestData.pm | 15 +++ db-updates.txt | 16 +++ 11 files changed, 518 insertions(+), 4 deletions(-) create mode 100644 IFComp/lib/IFComp/Controller/Admin/Questions.pm create mode 100644 IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm create mode 100644 IFComp/lib/IFComp/Schema/Result/Question.pm create mode 100644 IFComp/root/src/admin/questions/index.tt create mode 100644 IFComp/t/controller_Admin-Questions.t create mode 100644 db-updates.txt diff --git a/IFComp/lib/IFComp/Controller/Admin/Questions.pm b/IFComp/lib/IFComp/Controller/Admin/Questions.pm new file mode 100644 index 00000000..65a8e373 --- /dev/null +++ b/IFComp/lib/IFComp/Controller/Admin/Questions.pm @@ -0,0 +1,99 @@ +package IFComp::Controller::Admin::Questions; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller'; } + +=head1 NAME + +IFComp::Controller::Admin::Questions - Catalyst Controller + +=head1 DESCRIPTION + +Catalyst Controller. + +=head1 METHODS + +=cut + + +=head2 index + +=cut + +sub root : Chained('/admin/root') : PathPart('questions') : CaptureArgs(0) { + my ( $self, $c ) = @_; + + unless ( $c->user && $c->check_any_user_role('cheez') ) { + $c->res->redirect('/'); + $c->detach() + } + +} + +sub index : Chained('root') : PathPart('view') : Args(0) { + my ( $self, $c ) = @_; + + my @questions = $c->model('IFCompDB::Question')->all; + + $c->stash( + template => 'admin/questions/index.tt', + questions => \@questions, + ); +} + + +sub save_questions :Chained('root') :PathPart('save') :Args(0) :Method('POST') { + my ( $self, $c ) = @_; + + my $params = $c->req->body_parameters; + my $guard = $c->model('IFCompDB')->txn_scope_guard; + + foreach my $param_name ( keys %$params ) { + + if ( $param_name =~ /^question_(\d+)$/ ) { + my $question_id = $1; + my $question_text = $params->{$param_name}; + + my $question_row = $c->model('IFCompDB::Question')->find($question_id); + + if ($question_row) { + if ( $params->{"disable_$question_id"} ) { + $question_row->update({ disabled => 1 });; + } else { + $question_row->update({ disabled => 0 });; + } + $question_row->update({ question_text => $question_text }); + } + } + } + + if ( $params->{new_question} && $params->{new_question} =~ /\S/ ) { + $c->model('IFCompDB::Question')->create({ + question_text => $params->{new_question} + }); + } + + $guard->commit; + + $c->flash->{status_msg} = "Questions successfully updated."; + $c->res->redirect($c->uri_for('/admin/questions/view')); +} + + +=encoding utf8 + +=head1 AUTHOR + +Mark Musante + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/IFComp/lib/IFComp/Controller/Entry.pm b/IFComp/lib/IFComp/Controller/Entry.pm index ce9c1300..7bfc91b5 100644 --- a/IFComp/lib/IFComp/Controller/Entry.pm +++ b/IFComp/lib/IFComp/Controller/Entry.pm @@ -72,7 +72,9 @@ sub root : Chained('/') : PathPart('entry') : CaptureArgs(0) { sub fetch_entry : Chained('root') : PathPart('') : CaptureArgs(1) { my ( $self, $c, $id ) = @_; - my $entry = $c->model('IFCompDB::Entry')->find($id); + my $entry = $c->model('IFCompDB::Entry')->find($id, { + prefetch => { 'entry_answers' => 'question' }, + }); if ( $entry && $entry->author->id eq $c->user->get_object->id ) { $c->stash->{entry} = $entry; $self->entry($entry); @@ -111,9 +113,12 @@ sub create : Chained('root') : PathPart('create') : Args(0) { comp => $c->stash->{current_comp}, author => $c->user->get_object->id, ); + my @questions = $c->model('IFCompDB::Question')->all; $c->stash( entry => - $c->model('IFCompDB::Entry')->new_result( \%new_result_args ) ); + $c->model('IFCompDB::Entry')->new_result( \%new_result_args ), + uk_compliance => \@questions, + ); if ( $self->_process_form($c) ) { $c->user->send_author_reminder_email; $c->res->redirect( $c->uri_for_action('/entry/list') ); @@ -257,6 +262,8 @@ sub _process_form { template => 'entry/update.tt', ); + my @questions = $c->model('IFCompDB::Question')->all; + my $params_ref = $c->req->parameters; foreach (qw( main_upload walkthrough_upload cover_upload )) { my $param = "entry.$_"; @@ -328,6 +335,21 @@ sub _process_form { } } + for my $q (@questions) { + $c->log->debug("Question " . $q->question_text . ", id = " . $q->id); + my $val = "uk_compliance.q_" . $q->id; + my $ans = "no"; + if (defined( $params_ref->{$val} ) ) { + $ans = "yes"; + } + + $c->model('IFCompDB::EntryAnswer')->update_or_create({ + entry_id => $entry->id, + question_id => $q->id, + answer => $ans, + }); + } + my $genai_data = $params_ref->{"entry.genai"}; my $value = 0; if ( ref($genai_data) eq 'ARRAY' ) { diff --git a/IFComp/lib/IFComp/Schema/Result/Entry.pm b/IFComp/lib/IFComp/Schema/Result/Entry.pm index e4f7ecab..4e3d1392 100644 --- a/IFComp/lib/IFComp/Schema/Result/Entry.pm +++ b/IFComp/lib/IFComp/Schema/Result/Entry.pm @@ -443,6 +443,21 @@ __PACKAGE__->belongs_to( { is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT" }, ); +=head2 entry_answers + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "entry_answers", + "IFComp::Schema::Result::EntryAnswer", + { "foreign.entry_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + =head2 entry_coauthors Type: has_many @@ -520,8 +535,8 @@ __PACKAGE__->has_many( #>>> -# Created by DBIx::Class::Schema::Loader v0.07052 @ 2024-08-05 22:40:52 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BA11TUZSbhEvXq6M5++njA +# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 16:47:19 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:FZfThHgy9NQ+My4Z+c6WJA __PACKAGE__->add_columns( '+coauthor_code' => { dynamic_default_on_create => '_generate_unique_coauthor_code', }, ); diff --git a/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm b/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm new file mode 100644 index 00000000..b7a27d08 --- /dev/null +++ b/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm @@ -0,0 +1,124 @@ +#<<< +use utf8; +package IFComp::Schema::Result::EntryAnswer; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +IFComp::Schema::Result::EntryAnswer + +=cut + +use strict; +use warnings; + + +=head1 BASE CLASS: L + +=cut + +use Moose; +use MooseX::NonMoose; +use MooseX::MarkAsMethods autoclean => 1; +extends 'IFComp::Schema::Result'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("entry_answers"); + +=head1 ACCESSORS + +=head2 entry_id + + data_type: 'integer' + extra: {unsigned => 1} + is_foreign_key: 1 + is_nullable: 0 + +=head2 question_id + + data_type: 'integer' + is_foreign_key: 1 + is_nullable: 0 + +=head2 answer + + data_type: 'varchar' + is_nullable: 1 + size: 255 + +=cut + +__PACKAGE__->add_columns( + "entry_id", + { + data_type => "integer", + extra => { unsigned => 1 }, + is_foreign_key => 1, + is_nullable => 0, + }, + "question_id", + { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, + "answer", + { data_type => "varchar", is_nullable => 1, size => 255 }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("entry_id", "question_id"); + +=head1 RELATIONS + +=head2 entry + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "entry", + "IFComp::Schema::Result::Entry", + { id => "entry_id" }, + { is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT" }, +); + +=head2 question + +Type: belongs_to + +Related object: L + +=cut + +__PACKAGE__->belongs_to( + "question", + "IFComp::Schema::Result::Question", + { id => "question_id" }, + { is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT" }, +); + +#>>> + +# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 16:47:19 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2zeKaGFExxptUHaSfZ84PA + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +__PACKAGE__->meta->make_immutable; +1; diff --git a/IFComp/lib/IFComp/Schema/Result/Question.pm b/IFComp/lib/IFComp/Schema/Result/Question.pm new file mode 100644 index 00000000..cb000c7c --- /dev/null +++ b/IFComp/lib/IFComp/Schema/Result/Question.pm @@ -0,0 +1,101 @@ +#<<< +use utf8; +package IFComp::Schema::Result::Question; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +IFComp::Schema::Result::Question + +=cut + +use strict; +use warnings; + + +=head1 BASE CLASS: L + +=cut + +use Moose; +use MooseX::NonMoose; +use MooseX::MarkAsMethods autoclean => 1; +extends 'IFComp::Schema::Result'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("questions"); + +=head1 ACCESSORS + +=head2 id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 question_text + + data_type: 'varchar' + is_nullable: 0 + size: 255 + +=head2 disabled + + data_type: 'tinyint' + default_value: 1 + is_nullable: 1 + +=cut + +__PACKAGE__->add_columns( + "id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "question_text", + { data_type => "varchar", is_nullable => 0, size => 255 }, + "disabled", + { data_type => "tinyint", default_value => 1, is_nullable => 1 }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("id"); + +=head1 RELATIONS + +=head2 entry_answers + +Type: has_many + +Related object: L + +=cut + +__PACKAGE__->has_many( + "entry_answers", + "IFComp::Schema::Result::EntryAnswer", + { "foreign.question_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + +#>>> + +# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 19:53:01 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zRSkaJHmZmFhsF+2NtgpTg + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +__PACKAGE__->meta->make_immutable; +1; diff --git a/IFComp/root/src/admin/index.tt b/IFComp/root/src/admin/index.tt index 741994ad..b210204a 100644 --- a/IFComp/root/src/admin/index.tt +++ b/IFComp/root/src/admin/index.tt @@ -23,6 +23,7 @@
  • User Validation
  • Download CSV of Results
  • Download CSV of Payout Results
  • +
  • Modify UK Compliance Questions
  • [% END %] [% IF c.check_user_roles( 'prizemanager' ) %]
  • Prize Management
  • diff --git a/IFComp/root/src/admin/questions/index.tt b/IFComp/root/src/admin/questions/index.tt new file mode 100644 index 00000000..93d2a646 --- /dev/null +++ b/IFComp/root/src/admin/questions/index.tt @@ -0,0 +1,79 @@ +
    +

    UK Compliance Questions

    + + [% IF c.flash.status_msg %] + +[% END %] + +
    + +
    +
    + + + + + + + + + [% FOR q IN questions %] + + + + + [% END %] + + + + + + +
    Question TextActions
    + +
    Question text cannot be blank.
    +
    +
    + + +
    +
    +
    + + + + +
    +
    +   +
    +
    + + +
    + +
    +
    diff --git a/IFComp/root/src/entry/_form.tt b/IFComp/root/src/entry/_form.tt index df9b82e7..c5955713 100644 --- a/IFComp/root/src/entry/_form.tt +++ b/IFComp/root/src/entry/_form.tt @@ -230,6 +230,38 @@ You may optionally provide a brief warning that your work contains emotionally i + +
    +

    UK Compliance Information

    +
    +

    +Due to requirements of the UK Online Safety Act (OSA), +some entries may require additional review and could be unavailable to judges in the United +Kingdom. In the 2025 post-competition survey, approximately 11% of responding authors and 8% of +responding judges reported that these restrictions affected their competition experience. +

    + +

    +[% FOR q IN entry.entry_answers %] + [% IF NOT q.question.disabled %] + +
    + [% END %] +[% END %] +

    + +

    +Please note: This information helps organizers identify entries that may require +additional review, but all entries will be reviewed regardless of the selections made above. +Selections do not automatically determine whether an entry will be available in the United +Kingdom. If you have questions or would like to discuss the unique aspects of your entry, please +contact us at ifcomp@ifcomp.org. +

    + +
    +
    + +

    Displayed name(s) and contact info

    diff --git a/IFComp/t/controller_Admin-Questions.t b/IFComp/t/controller_Admin-Questions.t new file mode 100644 index 00000000..4b00d0ae --- /dev/null +++ b/IFComp/t/controller_Admin-Questions.t @@ -0,0 +1,10 @@ +use strict; +use warnings; +use Test::More; + + +use Catalyst::Test 'IFComp'; +use IFComp::Controller::Admin::Questions; + +ok( request('/admin/questions')->is_success, 'Request should succeed' ); +done_testing(); diff --git a/IFComp/t/lib/IFCompTestData.pm b/IFComp/t/lib/IFCompTestData.pm index 8dce581e..c6f135ec 100644 --- a/IFComp/t/lib/IFCompTestData.pm +++ b/IFComp/t/lib/IFCompTestData.pm @@ -25,6 +25,21 @@ sub add_test_data_to_schema { ], ); + $schema->populate( + 'Question', + [ [ 'id', 'question_text', 'disabled' ], + [ 1, "Images depicting sexual content",0], + [ 2, "Suicide or self-harm",0], + [ 3, "Eating disorders",0], + [ 4, "Hate speech, discriminatory content, or content targeting people based on protected characteristics",0], + [ 5, "Graphic or realistic depictions of violence/blood/gore",0], + [ 6, "Bullying or harassment",0], + [ 7, "Harmful substance use or abuse",0], + [ 8, "Dangerous challenges, stunts, or risky activities",0], + [ 9, "None of the above",0], + ], + ); + $schema->populate( 'User', [ [ 'id', 'name', diff --git a/db-updates.txt b/db-updates.txt new file mode 100644 index 00000000..a70ea47b --- /dev/null +++ b/db-updates.txt @@ -0,0 +1,16 @@ +Entry Questions + +CREATE TABLE questions ( + id INT AUTO_INCREMENT PRIMARY KEY, + question_text VARCHAR(255) NOT NULL, + disabled BOOLEAN DEFAULT TRUE +); + +CREATE TABLE entry_answers ( + entry_id int(10) unsigned, + question_id INT, + answer VARCHAR(255), + PRIMARY KEY (entry_id, question_id), + FOREIGN KEY (entry_id) REFERENCES entry(id), + FOREIGN KEY (question_id) REFERENCES questions(id) +); From 9bd481ad0d006f2e6a8589a891cdc1588079a123 Mon Sep 17 00:00:00 2001 From: Mark Musante Date: Tue, 16 Jun 2026 16:55:54 -0400 Subject: [PATCH 2/5] cascade delete when withdrawing an entry --- .../lib/IFComp/Controller/Admin/Questions.pm | 43 +++++++++---------- IFComp/lib/IFComp/Controller/Entry.pm | 40 +++++++++-------- IFComp/lib/IFComp/Schema/Result/Entry.pm | 4 +- .../lib/IFComp/Schema/Result/EntryAnswer.pm | 7 ++- IFComp/lib/IFComp/Schema/Result/Question.pm | 1 - IFComp/root/src/entry/_form.tt | 17 ++++++-- IFComp/t/controller_Admin-Questions.t | 1 - IFComp/t/lib/IFCompTestData.pm | 25 ++++++----- db-updates.txt | 2 +- 9 files changed, 77 insertions(+), 63 deletions(-) diff --git a/IFComp/lib/IFComp/Controller/Admin/Questions.pm b/IFComp/lib/IFComp/Controller/Admin/Questions.pm index 65a8e373..1ed0ea2f 100644 --- a/IFComp/lib/IFComp/Controller/Admin/Questions.pm +++ b/IFComp/lib/IFComp/Controller/Admin/Questions.pm @@ -16,7 +16,6 @@ Catalyst Controller. =cut - =head2 index =cut @@ -26,7 +25,7 @@ sub root : Chained('/admin/root') : PathPart('questions') : CaptureArgs(0) { unless ( $c->user && $c->check_any_user_role('cheez') ) { $c->res->redirect('/'); - $c->detach() + $c->detach(); } } @@ -42,45 +41,45 @@ sub index : Chained('root') : PathPart('view') : Args(0) { ); } - -sub save_questions :Chained('root') :PathPart('save') :Args(0) :Method('POST') { +sub save_questions : Chained('root') : PathPart('save') : Args(0) : + Method('POST') { my ( $self, $c ) = @_; - + my $params = $c->req->body_parameters; my $guard = $c->model('IFCompDB')->txn_scope_guard; - + foreach my $param_name ( keys %$params ) { - + if ( $param_name =~ /^question_(\d+)$/ ) { my $question_id = $1; my $question_text = $params->{$param_name}; - - my $question_row = $c->model('IFCompDB::Question')->find($question_id); - + + my $question_row = + $c->model('IFCompDB::Question')->find($question_id); + if ($question_row) { if ( $params->{"disable_$question_id"} ) { - $question_row->update({ disabled => 1 });; - } else { - $question_row->update({ disabled => 0 });; + $question_row->update( { disabled => 1 } ); + } + else { + $question_row->update( { disabled => 0 } ); } - $question_row->update({ question_text => $question_text }); + $question_row->update( { question_text => $question_text } ); } } } - + if ( $params->{new_question} && $params->{new_question} =~ /\S/ ) { - $c->model('IFCompDB::Question')->create({ - question_text => $params->{new_question} - }); + $c->model('IFCompDB::Question') + ->create( { question_text => $params->{new_question} } ); } - + $guard->commit; - + $c->flash->{status_msg} = "Questions successfully updated."; - $c->res->redirect($c->uri_for('/admin/questions/view')); + $c->res->redirect( $c->uri_for('/admin/questions/view') ); } - =encoding utf8 =head1 AUTHOR diff --git a/IFComp/lib/IFComp/Controller/Entry.pm b/IFComp/lib/IFComp/Controller/Entry.pm index 7bfc91b5..d67df59f 100644 --- a/IFComp/lib/IFComp/Controller/Entry.pm +++ b/IFComp/lib/IFComp/Controller/Entry.pm @@ -61,10 +61,12 @@ sub root : Chained('/') : PathPart('entry') : CaptureArgs(0) { my @entries = $c->user->get_object->current_comp_entries; my $current_comp = $c->model('IFCompDB::Comp')->current_comp; + my @questions = $c->model('IFCompDB::Question')->all; $c->stash( - entries => \@entries, - current_comp => $current_comp, + entries => \@entries, + current_comp => $current_comp, + uk_compliance => \@questions, ); } @@ -72,9 +74,8 @@ sub root : Chained('/') : PathPart('entry') : CaptureArgs(0) { sub fetch_entry : Chained('root') : PathPart('') : CaptureArgs(1) { my ( $self, $c, $id ) = @_; - my $entry = $c->model('IFCompDB::Entry')->find($id, { - prefetch => { 'entry_answers' => 'question' }, - }); + my $entry = $c->model('IFCompDB::Entry') + ->find( $id, { prefetch => { 'entry_answers' => 'question' }, } ); if ( $entry && $entry->author->id eq $c->user->get_object->id ) { $c->stash->{entry} = $entry; $self->entry($entry); @@ -113,12 +114,9 @@ sub create : Chained('root') : PathPart('create') : Args(0) { comp => $c->stash->{current_comp}, author => $c->user->get_object->id, ); - my @questions = $c->model('IFCompDB::Question')->all; $c->stash( entry => - $c->model('IFCompDB::Entry')->new_result( \%new_result_args ), - uk_compliance => \@questions, - ); + $c->model('IFCompDB::Entry')->new_result( \%new_result_args ), ); if ( $self->_process_form($c) ) { $c->user->send_author_reminder_email; $c->res->redirect( $c->uri_for_action('/entry/list') ); @@ -336,18 +334,18 @@ sub _process_form { } for my $q (@questions) { - $c->log->debug("Question " . $q->question_text . ", id = " . $q->id); my $val = "uk_compliance.q_" . $q->id; my $ans = "no"; - if (defined( $params_ref->{$val} ) ) { + if ( defined( $params_ref->{$val} ) ) { $ans = "yes"; } - $c->model('IFCompDB::EntryAnswer')->update_or_create({ - entry_id => $entry->id, - question_id => $q->id, - answer => $ans, - }); + $c->model('IFCompDB::EntryAnswer')->update_or_create( + { entry_id => $entry->id, + question_id => $q->id, + answer => $ans, + } + ); } my $genai_data = $params_ref->{"entry.genai"}; @@ -449,8 +447,14 @@ sub _process_withdrawal_form { my ( $self, $c ) = @_; if ( $self->withdrawal_form->process( params => $c->req->parameters, ) ) { - $c->stash->{entry}->delete; - $c->flash->{entry_withdrawn} = $c->stash->{entry}->title; + $c->log->debug( "Delete " . $c->stash->{entry}->id ); + my $entry = + $c->model('IFCompDB::Entry')->find( $c->stash->{entry}->id ); + if ($entry) { + $c->log->debug( "Found entry id " . $entry->id ); + $entry->delete; + $c->flash->{entry_withdrawn} = $c->stash->{entry}->title; + } $c->res->redirect( $c->uri_for_action('/entry/list') ); } diff --git a/IFComp/lib/IFComp/Schema/Result/Entry.pm b/IFComp/lib/IFComp/Schema/Result/Entry.pm index 4e3d1392..12722016 100644 --- a/IFComp/lib/IFComp/Schema/Result/Entry.pm +++ b/IFComp/lib/IFComp/Schema/Result/Entry.pm @@ -535,8 +535,8 @@ __PACKAGE__->has_many( #>>> -# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 16:47:19 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:FZfThHgy9NQ+My4Z+c6WJA +# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 20:51:39 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:pZ9XCGIkzyTQGGz4JNbWpw __PACKAGE__->add_columns( '+coauthor_code' => { dynamic_default_on_create => '_generate_unique_coauthor_code', }, ); diff --git a/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm b/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm index b7a27d08..032efec4 100644 --- a/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm +++ b/IFComp/lib/IFComp/Schema/Result/EntryAnswer.pm @@ -95,7 +95,7 @@ __PACKAGE__->belongs_to( "entry", "IFComp::Schema::Result::Entry", { id => "entry_id" }, - { is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT" }, + { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, ); =head2 question @@ -115,9 +115,8 @@ __PACKAGE__->belongs_to( #>>> -# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 16:47:19 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2zeKaGFExxptUHaSfZ84PA - +# Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 20:51:39 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zfm0Hfg8Ac4nMJbK/YwfTg # You can replace this text with custom code or comments, and it will be preserved on regeneration __PACKAGE__->meta->make_immutable; diff --git a/IFComp/lib/IFComp/Schema/Result/Question.pm b/IFComp/lib/IFComp/Schema/Result/Question.pm index cb000c7c..12793b21 100644 --- a/IFComp/lib/IFComp/Schema/Result/Question.pm +++ b/IFComp/lib/IFComp/Schema/Result/Question.pm @@ -95,7 +95,6 @@ __PACKAGE__->has_many( # Created by DBIx::Class::Schema::Loader v0.07053 @ 2026-06-16 19:53:01 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zRSkaJHmZmFhsF+2NtgpTg - # You can replace this text with custom code or comments, and it will be preserved on regeneration __PACKAGE__->meta->make_immutable; 1; diff --git a/IFComp/root/src/entry/_form.tt b/IFComp/root/src/entry/_form.tt index c5955713..1f8a0b9c 100644 --- a/IFComp/root/src/entry/_form.tt +++ b/IFComp/root/src/entry/_form.tt @@ -242,10 +242,19 @@ responding judges reported that these restrictions affected their competition ex

    -[% FOR q IN entry.entry_answers %] - [% IF NOT q.question.disabled %] - -
    +[% IF entry.id %] + [% FOR q IN entry.entry_answers %] + [% IF NOT q.question.disabled %] + +
    + [% END %] + [% END %] +[% ELSE %] + [% FOR q IN uk_compliance %] + [% IF NOT q.disabled %] + +
    + [% END %] [% END %] [% END %]

    diff --git a/IFComp/t/controller_Admin-Questions.t b/IFComp/t/controller_Admin-Questions.t index 4b00d0ae..b7d95348 100644 --- a/IFComp/t/controller_Admin-Questions.t +++ b/IFComp/t/controller_Admin-Questions.t @@ -2,7 +2,6 @@ use strict; use warnings; use Test::More; - use Catalyst::Test 'IFComp'; use IFComp::Controller::Admin::Questions; diff --git a/IFComp/t/lib/IFCompTestData.pm b/IFComp/t/lib/IFCompTestData.pm index c6f135ec..e51ca1dc 100644 --- a/IFComp/t/lib/IFCompTestData.pm +++ b/IFComp/t/lib/IFCompTestData.pm @@ -27,16 +27,21 @@ sub add_test_data_to_schema { $schema->populate( 'Question', - [ [ 'id', 'question_text', 'disabled' ], - [ 1, "Images depicting sexual content",0], - [ 2, "Suicide or self-harm",0], - [ 3, "Eating disorders",0], - [ 4, "Hate speech, discriminatory content, or content targeting people based on protected characteristics",0], - [ 5, "Graphic or realistic depictions of violence/blood/gore",0], - [ 6, "Bullying or harassment",0], - [ 7, "Harmful substance use or abuse",0], - [ 8, "Dangerous challenges, stunts, or risky activities",0], - [ 9, "None of the above",0], + [ [ 'id', 'question_text', 'disabled' ], + [ 1, "Images depicting sexual content", 0 ], + [ 2, "Suicide or self-harm", 0 ], + [ 3, "Eating disorders", 0 ], + [ 4, + "Hate speech, discriminatory content, or content targeting people based on protected characteristics", + 0 + ], + [ 5, "Graphic or realistic depictions of violence/blood/gore", + 0 + ], + [ 6, "Bullying or harassment", 0 ], + [ 7, "Harmful substance use or abuse", 0 ], + [ 8, "Dangerous challenges, stunts, or risky activities", 0 ], + [ 9, "None of the above", 0 ], ], ); diff --git a/db-updates.txt b/db-updates.txt index a70ea47b..17c4441b 100644 --- a/db-updates.txt +++ b/db-updates.txt @@ -11,6 +11,6 @@ CREATE TABLE entry_answers ( question_id INT, answer VARCHAR(255), PRIMARY KEY (entry_id, question_id), - FOREIGN KEY (entry_id) REFERENCES entry(id), + FOREIGN KEY (entry_id) REFERENCES entry(id) ON DELETE CASCADE, FOREIGN KEY (question_id) REFERENCES questions(id) ); From 7815060975e19abc65ff83a8eb7aad4446ccd27f Mon Sep 17 00:00:00 2001 From: Mark Musante Date: Tue, 16 Jun 2026 17:34:37 -0400 Subject: [PATCH 3/5] cleanup debug output, and fix tests --- IFComp/lib/IFComp/Controller/Entry.pm | 2 -- IFComp/t/controller_Admin-Questions.t | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/IFComp/lib/IFComp/Controller/Entry.pm b/IFComp/lib/IFComp/Controller/Entry.pm index d67df59f..d504e966 100644 --- a/IFComp/lib/IFComp/Controller/Entry.pm +++ b/IFComp/lib/IFComp/Controller/Entry.pm @@ -447,11 +447,9 @@ sub _process_withdrawal_form { my ( $self, $c ) = @_; if ( $self->withdrawal_form->process( params => $c->req->parameters, ) ) { - $c->log->debug( "Delete " . $c->stash->{entry}->id ); my $entry = $c->model('IFCompDB::Entry')->find( $c->stash->{entry}->id ); if ($entry) { - $c->log->debug( "Found entry id " . $entry->id ); $entry->delete; $c->flash->{entry_withdrawn} = $c->stash->{entry}->title; } diff --git a/IFComp/t/controller_Admin-Questions.t b/IFComp/t/controller_Admin-Questions.t index b7d95348..8ddfd0b6 100644 --- a/IFComp/t/controller_Admin-Questions.t +++ b/IFComp/t/controller_Admin-Questions.t @@ -2,8 +2,24 @@ use strict; use warnings; use Test::More; +unless ( eval q{use Test::WWW::Mechanize::Catalyst 0.55; 1} ) { + plan skip_all => 'Test::WWW::Mechanize::Catalyst >= 0.55 required'; + exit 0; +} + +use FindBin; +use lib ("$FindBin::Bin/lib"); +use IFCompTest; +my $schema = IFCompTest->init_schema(); + use Catalyst::Test 'IFComp'; use IFComp::Controller::Admin::Questions; -ok( request('/admin/questions')->is_success, 'Request should succeed' ); +ok( my $mech = + Test::WWW::Mechanize::Catalyst->new( catalyst_app => 'IFComp' ), + 'Created mech object' +); + +IFCompTest::log_in_as_cheez($mech); +ok( $mech->get_ok('/admin/questions/view'), 'Request should succeed' ); done_testing(); From 04f111173042f1621107592ef560e3d6f96e0f1d Mon Sep 17 00:00:00 2001 From: Mark Musante Date: Sat, 20 Jun 2026 12:59:41 -0400 Subject: [PATCH 4/5] clarify purpose of questions --- IFComp/root/src/entry/_form.tt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/IFComp/root/src/entry/_form.tt b/IFComp/root/src/entry/_form.tt index 1f8a0b9c..b4a4b90b 100644 --- a/IFComp/root/src/entry/_form.tt +++ b/IFComp/root/src/entry/_form.tt @@ -241,6 +241,8 @@ Kingdom. In the 2025 post-competition survey, approximately 11% of responding au responding judges reported that these restrictions affected their competition experience.

    +

    Does your entry contain any of the following?

    +

    [% IF entry.id %] [% FOR q IN entry.entry_answers %] From fa5503de5e4d8e12b54abd7ea4e0e4e4e85b88b6 Mon Sep 17 00:00:00 2001 From: Mark Musante Date: Sat, 20 Jun 2026 13:18:38 -0400 Subject: [PATCH 5/5] clarifying the clarification --- IFComp/root/src/entry/_form.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IFComp/root/src/entry/_form.tt b/IFComp/root/src/entry/_form.tt index b4a4b90b..787a12b8 100644 --- a/IFComp/root/src/entry/_form.tt +++ b/IFComp/root/src/entry/_form.tt @@ -241,7 +241,7 @@ Kingdom. In the 2025 post-competition survey, approximately 11% of responding au responding judges reported that these restrictions affected their competition experience.

    -

    Does your entry contain any of the following?

    +

    Please select any topics that may be present in your entry:

    [% IF entry.id %]