Skip to content

Commit

Permalink
Merge pull request #84 from jsangmeister/fix-models
Browse files Browse the repository at this point in the history
Fix models & add rudimentary validation
  • Loading branch information
jsangmeister committed Apr 19, 2024
2 parents cb70d6d + 98307c5 commit 936d185
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 40 deletions.
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

0 comments on commit 936d185

Please sign in to comment.