Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix models & add rudimentary validation #84

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ jobs:
if: always()
run: make pyupgrade

# - name: Validate models.yml
# if: always()
# run: make validate-models
- name: Validate models.yml
if: always()
run: make validate-models
36 changes: 22 additions & 14 deletions dev/sql/schema_relational.sql
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ BEGIN
END;
$$ LANGUAGE plpgsql;

-- MODELS_YML_CHECKSUM = '959d3a581a8015a294d769587ebb1b6e'
-- MODELS_YML_CHECKSUM = 'bbd75cac13c55c82f772ae52df63aa96'
-- Type definitions

-- Table definitions
Expand Down Expand Up @@ -128,15 +128,13 @@ CREATE TABLE IF NOT EXISTS user_t (
is_demo_user boolean,
last_login timestamptz,
organization_management_level varchar(256) CONSTRAINT enum_user_organization_management_level CHECK (organization_management_level IN ('superadmin', 'can_manage_organization', 'can_manage_users')),
meeting_ids integer[],
organization_id integer GENERATED ALWAYS AS (1) STORED NOT NULL
);



comment on column user_t.saml_id is 'unique-key from IdP for SAML login';
comment on column user_t.organization_management_level is 'Hierarchical permission level for the whole organization.';
comment on column user_t.meeting_ids is 'Calculated. All ids from meetings calculated via meeting_user and group_ids as integers.';


CREATE TABLE IF NOT EXISTS meeting_user_t (
Expand Down Expand Up @@ -405,7 +403,6 @@ This email was generated automatically.',
font_projector_h1_id integer,
font_projector_h2_id integer,
committee_id integer NOT NULL,
user_ids integer[],
reference_projector_id integer NOT NULL,
list_of_speakers_countdown_id integer,
poll_countdown_id integer,
Expand All @@ -420,7 +417,6 @@ comment on column meeting_t.is_active_in_organization_id is 'Backrelation and bo
comment on column meeting_t.is_archived_in_organization_id is 'Backrelation and boolean flag at once';
comment on column meeting_t.list_of_speakers_default_structure_level_time is '0 disables structure level countdowns.';
comment on column meeting_t.list_of_speakers_intervention_time is '0 disables intervention speakers.';
comment on column meeting_t.user_ids is 'Calculated. All user ids from all users assigned to groups of this meeting.';


CREATE TABLE IF NOT EXISTS structure_level_t (
Expand Down Expand Up @@ -1133,6 +1129,12 @@ CREATE TABLE IF NOT EXISTS nm_meeting_present_user_ids_user_t (
PRIMARY KEY (meeting_id, user_id)
);

CREATE TABLE IF NOT EXISTS nm_meeting_user_ids_user_t (
meeting_id integer NOT NULL REFERENCES meeting_t (id),
user_id integer NOT NULL REFERENCES user_t (id),
PRIMARY KEY (meeting_id, user_id)
);

CREATE TABLE IF NOT EXISTS nm_group_meeting_user_ids_meeting_user_t (
group_id integer NOT NULL REFERENCES group_t (id),
meeting_user_id integer NOT NULL REFERENCES meeting_user_t (id),
Expand Down Expand Up @@ -1262,10 +1264,12 @@ CREATE OR REPLACE VIEW user_ AS SELECT *,
(select array_agg(o.id) from option_t o where o.content_object_id_user_id = u.id) as option_ids,
(select array_agg(v.id) from vote_t v where v.user_id = u.id) as vote_ids,
(select array_agg(v.id) from vote_t v where v.delegated_user_id = u.id) as delegated_vote_ids,
(select array_agg(p.id) from poll_candidate_t p where p.user_id = u.id) as poll_candidate_ids
(select array_agg(p.id) from poll_candidate_t p where p.user_id = u.id) as poll_candidate_ids,
(select array_agg(n.meeting_id) from nm_meeting_user_ids_user_t n where n.user_id = u.id) as meeting_ids
FROM user_t u;

comment on column user_.committee_ids is 'Calculated field: Returns committee_ids, where the user is manager or member in a meeting';
comment on column user_.meeting_ids is 'Calculated. All ids from meetings calculated via meeting_user and group_ids as integers.';

CREATE OR REPLACE VIEW meeting_user AS SELECT *,
(select array_agg(p.id) from personal_note_t p where p.meeting_user_id = m.id) as personal_note_ids,
Expand Down Expand Up @@ -1349,11 +1353,12 @@ CREATE OR REPLACE VIEW meeting AS SELECT *,
(select c.id from committee_t c where c.default_meeting_id = m.id) as default_meeting_for_committee_id,
(select array_agg(g.organization_tag_id) from gm_organization_tag_tagged_ids_t g where g.tagged_id_meeting_id = m.id) as organization_tag_ids,
(select array_agg(n.user_id) from nm_meeting_present_user_ids_user_t n where n.meeting_id = m.id) as present_user_ids,
(select array_agg(n.user_id) from nm_meeting_user_ids_user_t n where n.meeting_id = m.id) as user_ids,
(select array_agg(p.id) from projection_t p where p.content_object_id_meeting_id = m.id) as projection_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_agenda_item_list_in_meeting_id = m.id) as default_projector_agenda_item_list_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_topic_in_meeting_id = m.id) as default_projector_topic_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_list_of_speakers_in_meeting_id = m.id) as default_projector_list_of_speakers_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_current_los_in_meeting_id = m.id) as default_projector_current_list_of_speakers_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_current_los_in_meeting_id = m.id) as default_projector_current_los_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_motion_in_meeting_id = m.id) as default_projector_motion_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_amendment_in_meeting_id = m.id) as default_projector_amendment_ids,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_motion_block_in_meeting_id = m.id) as default_projector_motion_block_ids,
Expand All @@ -1366,6 +1371,7 @@ CREATE OR REPLACE VIEW meeting AS SELECT *,
(select array_agg(p.id) from projector_t p where p.used_as_default_projector_for_poll_in_meeting_id = m.id) as default_projector_poll_ids
FROM meeting_t m;

comment on column meeting.user_ids is 'Calculated. All user ids from all users assigned to groups of this meeting.';

CREATE OR REPLACE VIEW structure_level AS SELECT *,
(select array_agg(n.meeting_user_id) from nm_meeting_user_structure_level_ids_structure_level_t n where n.structure_level_id = s.id) as meeting_user_ids,
Expand Down Expand Up @@ -1809,12 +1815,12 @@ CREATE CONSTRAINT TRIGGER tr_ud_meeting_default_projector_list_of_speakers_ids A
FOR EACH ROW EXECUTE FUNCTION check_not_null_for_relation_lists('meeting', 'default_projector_list_of_speakers_ids', 'used_as_default_projector_for_list_of_speakers_in_meeting_id');


-- definition trigger not null for meeting.default_projector_current_list_of_speakers_ids against projector_t.used_as_default_projector_for_current_los_in_meeting_id
CREATE CONSTRAINT TRIGGER tr_i_meeting_default_projector_current_list_of_speakers_ids AFTER INSERT ON projector_t INITIALLY DEFERRED
FOR EACH ROW EXECUTE FUNCTION check_not_null_for_relation_lists('meeting', 'default_projector_current_list_of_speakers_ids', 'used_as_default_projector_for_current_los_in_meeting_id');
-- definition trigger not null for meeting.default_projector_current_los_ids against projector_t.used_as_default_projector_for_current_los_in_meeting_id
CREATE CONSTRAINT TRIGGER tr_i_meeting_default_projector_current_los_ids AFTER INSERT ON projector_t INITIALLY DEFERRED
FOR EACH ROW EXECUTE FUNCTION check_not_null_for_relation_lists('meeting', 'default_projector_current_los_ids', 'used_as_default_projector_for_current_los_in_meeting_id');

CREATE CONSTRAINT TRIGGER tr_ud_meeting_default_projector_current_list_of_speakers_ids AFTER UPDATE OF used_as_default_projector_for_current_los_in_meeting_id OR DELETE ON projector_t
FOR EACH ROW EXECUTE FUNCTION check_not_null_for_relation_lists('meeting', 'default_projector_current_list_of_speakers_ids', 'used_as_default_projector_for_current_los_in_meeting_id');
CREATE CONSTRAINT TRIGGER tr_ud_meeting_default_projector_current_los_ids AFTER UPDATE OF used_as_default_projector_for_current_los_in_meeting_id OR DELETE ON projector_t
FOR EACH ROW EXECUTE FUNCTION check_not_null_for_relation_lists('meeting', 'default_projector_current_los_ids', 'used_as_default_projector_for_current_los_in_meeting_id');


-- definition trigger not null for meeting.default_projector_motion_ids against projector_t.used_as_default_projector_for_motion_in_meeting_id
Expand Down Expand Up @@ -1937,6 +1943,7 @@ SQL nt:1Gr => user/option_ids:-> option/content_object_id
SQL nt:1r => user/vote_ids:-> vote/user_id
SQL nt:1r => user/delegated_vote_ids:-> vote/delegated_user_id
SQL nt:1r => user/poll_candidate_ids:-> poll_candidate/user_id
SQL nt:nt => user/meeting_ids:-> meeting/user_ids

FIELD 1rR: => meeting_user/user_id:-> user/
FIELD 1rR: => meeting_user/meeting_id:-> meeting/
Expand Down Expand Up @@ -2034,14 +2041,15 @@ FIELD 1rR: => meeting/committee_id:-> committee/
SQL 1t:1r => meeting/default_meeting_for_committee_id:-> committee/default_meeting_id
SQL nt:nGt => meeting/organization_tag_ids:-> organization_tag/tagged_ids
SQL nt:nt => meeting/present_user_ids:-> user/is_present_in_meeting_ids
SQL nt:nt => meeting/user_ids:-> user/meeting_ids
FIELD 1rR: => meeting/reference_projector_id:-> projector/
FIELD 1r: => meeting/list_of_speakers_countdown_id:-> projector_countdown/
FIELD 1r: => meeting/poll_countdown_id:-> projector_countdown/
SQL nt:1GrR => meeting/projection_ids:-> projection/content_object_id
SQL ntR:1r => meeting/default_projector_agenda_item_list_ids:-> projector/used_as_default_projector_for_agenda_item_list_in_meeting_id
SQL ntR:1r => meeting/default_projector_topic_ids:-> projector/used_as_default_projector_for_topic_in_meeting_id
SQL ntR:1r => meeting/default_projector_list_of_speakers_ids:-> projector/used_as_default_projector_for_list_of_speakers_in_meeting_id
SQL ntR:1r => meeting/default_projector_current_list_of_speakers_ids:-> projector/used_as_default_projector_for_current_los_in_meeting_id
SQL ntR:1r => meeting/default_projector_current_los_ids:-> projector/used_as_default_projector_for_current_los_in_meeting_id
SQL ntR:1r => meeting/default_projector_motion_ids:-> projector/used_as_default_projector_for_motion_in_meeting_id
SQL ntR:1r => meeting/default_projector_amendment_ids:-> projector/used_as_default_projector_for_amendment_in_meeting_id
SQL ntR:1r => meeting/default_projector_motion_block_ids:-> projector/used_as_default_projector_for_motion_block_in_meeting_id
Expand Down Expand Up @@ -2321,4 +2329,4 @@ There are 3 errors/warnings
projection/content: type:JSON is marked as a calculated field and not generated in schema
*/

/* Missing attribute handling for constant, on_delete, sqlTODO, sql, equal_fields, unique, deferred */
/* Missing attribute handling for constant, on_delete, equal_fields, unique, deferred */
2 changes: 2 additions & 0 deletions dev/src/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"required",
"read_only",
"constant",
"unique",
)


Expand Down Expand Up @@ -201,6 +202,7 @@ def check_field(
valid_attributes.append("equal_fields")
if nested and type in ("relation", "relation-list"):
valid_attributes.append("enum")
valid_attributes.extend(("reference", "deferred", "sql"))

for attr in field.keys():
if attr not in valid_attributes:
Expand Down
47 changes: 24 additions & 23 deletions models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# r = reference, will result in a FIELD
# to = to, collection with field get's an automatic sql in a view, if not together with `reference`
# R = required
# The first tuple symbols the relation from-to, the 2nd FIELD or SQL and primary or not, only valis for lists
# The first tuple symbols the relation from-to, the 2nd FIELD or SQL and primary or not, only valid for lists
# The original of the following list is used in source code as `decision_list`
# ("1Gr", ""): (FieldSqlErrorType.FIELD, False),
# ("1GrR", ""): (FieldSqlErrorType.FIELD, False),
Expand Down Expand Up @@ -362,15 +362,15 @@ user:
restriction_mode: E
read_only: true
description: "Calculated field: Returns committee_ids, where the user is manager or member in a meeting"
sqlTODO: >-
(select array_agg(committee_id) from
select m.committee_id as committee_id from group_to_user gtu
join groupT g on g.id = gtu.group_id
join meetingT m on m.id = g.meeting_id
where gtu.user_id = u.id
union
select ctu.committee_id as committee_id from committee_manager_to_user ctu where ctu.user_id = u.id
) as committee_ids
# sql: >- # TODO
# (select array_agg(committee_id) from
# select m.committee_id as committee_id from group_to_user gtu
# join groupT g on g.id = gtu.group_id
# join meetingT m on m.id = g.meeting_id
# where gtu.user_id = u.id
# union
# select ctu.committee_id as committee_id from committee_manager_to_user ctu where ctu.user_id = u.id
# ) as committee_ids

# committee specific permissions
committee_management_ids:
Expand Down Expand Up @@ -414,7 +414,7 @@ user:
type: number[]
description: Calculated. All ids from meetings calculated via meeting_user and group_ids as integers.
read_only: true
sql: todo
# sql: todo
restriction_mode: E
organization_id:
type: relation
Expand Down Expand Up @@ -747,15 +747,15 @@ committee:
restriction_mode: A
read_only: true
description: "Calculated field: All users which are in a group of a meeting, belonging to the committee or beeing manager of the committee"
sqlTODO: >-
(select array_agg(user_id) from
select gtu.user_id as user_id from meetingT m
join groupT g on g.meeting_id = m.id
join group_to_user gtu on gtu.group_id = g.id
where m.committee_id = c.id
union
select ctu.user_id as user_id from committee_manager_to_user ctu where ctu.committee_id = c.id
) as user_ids
# sql: >- # TODO
# (select array_agg(user_id) from
# select gtu.user_id as user_id from meetingT m
# join groupT g on g.meeting_id = m.id
# join group_to_user gtu on gtu.group_id = g.id
# where m.committee_id = c.id
# union
# select ctu.user_id as user_id from committee_manager_to_user ctu where ctu.committee_id = c.id
# ) as user_ids
manager_ids:
type: relation-list
to: user/committee_management_ids
Expand Down Expand Up @@ -1767,12 +1767,12 @@ meeting:
restriction_mode: B
logo_pdf_footer_l_id:
type: relation
to: mediafile/used_as_logo_pdf_header_l_in_meeting_id
to: mediafile/used_as_logo_pdf_footer_l_in_meeting_id
reference: mediafile
restriction_mode: B
logo_pdf_footer_r_id:
type: relation
to: mediafile/used_as_logo_pdf_header_l_in_meeting_id
to: mediafile/used_as_logo_pdf_footer_r_in_meeting_id
reference: mediafile
restriction_mode: B
logo_pdf_ballot_paper_id:
Expand Down Expand Up @@ -1844,6 +1844,7 @@ meeting:
type: number[]
description: Calculated. All user ids from all users assigned to groups of this meeting.
read_only: true
# sql: todo
restriction_mode: B
reference_projector_id:
type: relation
Expand Down Expand Up @@ -1881,7 +1882,7 @@ meeting:
to: projector/used_as_default_projector_for_list_of_speakers_in_meeting_id
restriction_mode: B
required: true
default_projector_current_list_of_speakers_ids:
default_projector_current_los_ids:
type: relation-list
to: projector/used_as_default_projector_for_current_los_in_meeting_id
restriction_mode: B
Expand Down