Skip to content

Commit 54c4738

Browse files
authored
feat: New schema for reviews backend. | NPG-000 (#731)
# Description This PR introduces the updated schema for event-db to support the reviews backend.
1 parent 3c1c8cd commit 54c4738

File tree

13 files changed

+229
-68
lines changed

13 files changed

+229
-68
lines changed

docker/voting-node.dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ FROM jormungandr:latest as jorm
88

99
# stage 3
1010
FROM python as poetry
11-
RUN pip install poetry==1.8.0
11+
RUN pip install poetry==2.0.1
1212

1313
# Add python codebase
1414
COPY . /voting

services/voting-node/Earthfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ builder:
2121
zlib1g-dev
2222

2323
# Install Poetry
24-
RUN curl -sSL https://install.python-poetry.org | python3 - --version 1.8.0
24+
RUN curl -sSL https://install.python-poetry.org | python3 - --version 2.0.1
2525

2626
SAVE IMAGE --cache-hint
2727

@@ -42,6 +42,7 @@ deps:
4242
RUN poetry config installer.max-workers 10
4343
# Install package dependencies without the voting_node package
4444
RUN poetry install --only main --no-root
45+
RUN poetry self add poetry-plugin-export
4546

4647
# Copy the voting_node source code
4748
COPY --dir voting_node README.md ./
File renamed without changes.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
-- Catalyst Event Database
2+
3+
-- Subscription Table
4+
-- This table stores the subscriptions for users in the reviews module
5+
6+
CREATE TABLE subscription
7+
(
8+
row_id SERIAL PRIMARY KEY,
9+
user_id INTEGER NOT NULL,
10+
event_id INTEGER NOT NULL,
11+
role INTEGER NOT NULL,
12+
status INTEGER NOT NULL,
13+
extra JSONB NULL,
14+
15+
FOREIGN KEY (user_id) REFERENCES catalyst_user(row_id) ON DELETE CASCADE,
16+
FOREIGN KEY (event_id) REFERENCES event(row_id) ON DELETE CASCADE
17+
);
18+
19+
CREATE UNIQUE INDEX subscription_idx ON subscription(user_id,event_id,role);
20+
21+
COMMENT ON TABLE subscription IS '
22+
A subscription describes the possible roles of a single user for an event.
23+
A user can participate in multiple events active as multiple roles.
24+
For this reason this dedicated table tracks all active roles for a user related
25+
to a specific event and stores meta information about them.
26+
Some of these subscriptions will be automatically created by the system.
27+
The presence/status of subscriptions will determine user capabilities in the app.
28+
';
29+
30+
COMMENT ON COLUMN subscription.user_id IS 'The user ID this subscription belongs to.';
31+
COMMENT ON COLUMN subscription.event_id IS 'The event ID this subscription belongs to.';
32+
33+
COMMENT ON COLUMN subscription.role IS
34+
'This field describes the role of the user for this subscription.
35+
Possible values:
36+
0: For LV0 Community Reviewers
37+
1: For LV1 Community Reviewers
38+
2: For LV2 Moderators';
39+
40+
COMMENT ON COLUMN subscription.extra IS
41+
'This field is used to store all meta information about a subscription.
42+
Specifically:
43+
44+
anonymous_id: str,
45+
subscription_date: datetime,
46+
preferred_categories: [int],
47+
reward_address: str
48+
';
49+
50+
51+
-- Allocation - Defines the relationship between users and proposals or proposals_reviews
52+
-- to describe:
53+
-- - the ownership of a proposal.
54+
-- - the allocation of the reviews that needs to be done.
55+
-- - the allocation of moderations that needs to be done.
56+
57+
CREATE TABLE allocation (
58+
row_id SERIAL PRIMARY KEY,
59+
proposal_id INTEGER NULL,
60+
review_id INTEGER NULL,
61+
user_id INTEGER NOT NULL,
62+
type INTEGER NOT NULL,
63+
64+
FOREIGN KEY (proposal_id) REFERENCES proposal(row_id) ON DELETE CASCADE,
65+
FOREIGN KEY (review_id) REFERENCES proposal_review(row_id) ON DELETE CASCADE,
66+
FOREIGN KEY (user_id) REFERENCES catalyst_user(row_id) ON DELETE CASCADE
67+
);
68+
69+
70+
COMMENT ON TABLE allocation IS 'The relationship between users and proposals or proposals_reviews.';
71+
COMMENT ON COLUMN allocation.row_id IS 'Synthetic ID of this relationship.';
72+
COMMENT ON COLUMN allocation.proposal_id IS 'The proposal ID the relationship belongs to.';
73+
COMMENT ON COLUMN allocation.review_id IS 'The review ID the relationship belongs to.';
74+
COMMENT ON COLUMN allocation.user_id IS 'The user ID the relationship belongs to.';
75+
COMMENT ON COLUMN allocation.type IS 'The type of relationship stored.
76+
Possible values:
77+
0: proposal ownership relation. proposal_id and user_id are required
78+
1: proposal allocated for review. proposal_id and user_id are required
79+
2: review allocated for moderation. review_id and user_id are required';
80+
81+
CREATE INDEX idx_allocation_proposal_type ON allocation(proposal_id, type) WHERE proposal_id IS NOT NULL;
82+
CREATE INDEX idx_allocation_review_type ON allocation(review_id, type) WHERE review_id IS NOT NULL;
83+
CREATE INDEX idx_allocation_user_type ON allocation(user_id, type);
84+
85+
86+
-- Moderation - Defines the moderation submitted by users for each proposal_review.
87+
88+
CREATE TABLE moderation (
89+
row_id SERIAL PRIMARY KEY,
90+
review_id INTEGER NOT NULL,
91+
user_id INTEGER NOT NULL,
92+
classification INTEGER NOT NULL,
93+
rationale VARCHAR,
94+
UNIQUE (review_id, user_id),
95+
96+
FOREIGN KEY (review_id) REFERENCES proposal_review(row_id) ON DELETE CASCADE,
97+
FOREIGN KEY (user_id) REFERENCES catalyst_user(row_id) ON DELETE CASCADE
98+
);
99+
100+
101+
COMMENT ON TABLE moderation IS 'An individual moderation for a proposal review.';
102+
COMMENT ON COLUMN moderation.row_id IS 'Synthetic ID of this moderation.';
103+
COMMENT ON COLUMN moderation.review_id IS 'The review ID the moderation belongs to.';
104+
COMMENT ON COLUMN moderation.user_id IS 'The user ID the moderation belongs to.';
105+
COMMENT ON COLUMN moderation.classification IS 'The value used to describe the moderation (e.g. 0: excluded, 1: included).';
106+
COMMENT ON COLUMN moderation.rationale IS 'The rationale for the given classification.';
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- Catalyst Event Database
2+
3+
-- Catalyst ID map Table
4+
-- This table stores the relationship between a catalyst ID and an email address.
5+
6+
CREATE TABLE catalyst_id_map
7+
(
8+
row_id SERIAL PRIMARY KEY,
9+
catalyst_id VARCHAR NOT NULL,
10+
email VARCHAR NOT NULL,
11+
username VARCHAR NOT NULL,
12+
signed_email VARCHAR NOT NULL,
13+
status INTEGER NOT NULL,
14+
confirmation_token VARCHAR,
15+
confirmation_requested_at TIMESTAMP,
16+
confirmed_at TIMESTAMP,
17+
18+
UNIQUE(catalyst_id)
19+
);
20+
21+
CREATE UNIQUE INDEX catalyst_id_idx ON catalyst_id_map(catalyst_id, email);
22+
23+
COMMENT ON TABLE catalyst_id_map IS '
24+
The `catalyst_id_map` table is used to store the map between the CatalystID and email/username for each user.
25+
Because the Catalyst RBAC registration are stored on-chain, and for this reason are publicly accessible,
26+
sensitive information like email address will be stored in a centralized DB, keeping a reference to the CatalystID.
27+
The email address is stored only when its signature corresponds to the CatalystID.
28+
';
29+
COMMENT ON COLUMN catalyst_id_map.catalyst_id IS '
30+
It contains the unique part of the CatalystID.
31+
Given a full CatalystID like `id.catalyst://[email protected]/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE`
32+
The scheme and the username are omitted and only the unique part `preprod.cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE`
33+
is stored in this field.
34+
';
35+
COMMENT ON COLUMN catalyst_id_map.email IS 'The email address stored in plaintext.';
36+
COMMENT ON COLUMN catalyst_id_map.username IS 'The username extracted from the CatalystID stored in plaintext.';
37+
COMMENT ON COLUMN catalyst_id_map.signed_email IS 'The signed document that includes the email address.';
38+
COMMENT ON COLUMN catalyst_id_map.status IS '
39+
Describes the status of an account:
40+
0: Inactive
41+
1: Active
42+
2: Banned.';
43+
COMMENT ON COLUMN catalyst_id_map.confirmation_token IS 'The token that is generated for the email confirmation.';
44+
COMMENT ON COLUMN catalyst_id_map.confirmation_requested_at IS 'The timestamp to validate confirmation token validity.';
45+
COMMENT ON COLUMN catalyst_id_map.confirmed_at IS 'The timestamp of the email confirmation.';
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
-- Catalyst Event Database
2+
3+
-- User Table
4+
-- This table stores the users for the reviews module
5+
6+
CREATE TABLE catalyst_user
7+
(
8+
row_id SERIAL PRIMARY KEY,
9+
catalyst_id INTEGER NOT NULL,
10+
enc_password VARCHAR NOT NULL,
11+
salt VARCHAR NOT NULL,
12+
extra JSONB NULL,
13+
14+
FOREIGN KEY(catalyst_id) REFERENCES catalyst_id_map(row_id) ON DELETE CASCADE
15+
);
16+
17+
CREATE UNIQUE INDEX user_catalyst_id_idx ON catalyst_user(catalyst_id);
18+
19+
20+
COMMENT ON TABLE catalyst_user IS '
21+
This tables stores the user account for the Review Module.
22+
It contains a reference to the catalyst_id that is used as public and unique identifier.
23+
';
24+
25+
COMMENT ON COLUMN catalyst_user.catalyst_id IS 'The catalyst_id this account belongs to.';
26+
COMMENT ON COLUMN catalyst_user.enc_password IS 'The encrypted password.';
27+
COMMENT ON COLUMN catalyst_user.salt IS 'The salt for the password encryption.';
28+
COMMENT ON COLUMN catalyst_user.extra IS
29+
'This field is used to store all meta information about a user that
30+
are required by the application. Specifically:
31+
32+
admin: bool,
33+
username: str,
34+
registration_date: datetime,
35+
due_diligence: {
36+
status: int,
37+
due_diligence_id: str,
38+
url: str
39+
},
40+
historic_stats: {
41+
"reviews": {
42+
"active_funds": int,
43+
"submitted": int,
44+
"blank": int,
45+
"valid": int
46+
},
47+
"moderations": {
48+
"active_funds": int,
49+
"submitted": int,
50+
"allocated": int,
51+
}
52+
}
53+
';

src/event-db/migrations/V4__proposal_tables.sql renamed to src/event-db/migrations/V6__proposal_tables.sql

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -99,52 +99,47 @@ COMMENT ON COLUMN reviewer_level.event_id IS 'The specific Event ID this review
9999
CREATE TABLE proposal_review (
100100
row_id SERIAL PRIMARY KEY,
101101
proposal_id INTEGER NOT NULL,
102+
user_id INTEGER NOT NULL,
102103
assessor VARCHAR NOT NULL,
103104
assessor_level INTEGER,
104-
reward_address TEXT,
105105

106-
-- These fields are deprecated and WILL BE removed in a future migration.
107-
-- They MUST only be used for Vit-SS compatibility.
108106
impact_alignment_rating_given INTEGER,
109107
impact_alignment_note VARCHAR,
110108
feasibility_rating_given INTEGER,
111109
feasibility_note VARCHAR,
112110
auditability_rating_given INTEGER,
113111
auditability_note VARCHAR,
112+
allocated INTEGER,
114113
ranking INTEGER,
115114
flags JSONB NULL,
116115

117-
FOREIGN KEY (proposal_id) REFERENCES proposal(row_id) ON DELETE CASCADE,
118-
FOREIGN KEY (assessor_level) REFERENCES reviewer_level(row_id) ON DELETE CASCADE
116+
FOREIGN KEY (user_id) REFERENCES catalyst_user(row_id) ON DELETE SET NULL,
117+
FOREIGN KEY (proposal_id) REFERENCES proposal(row_id) ON DELETE CASCADE
119118
);
120119

121120
COMMENT ON TABLE proposal_review IS 'All Reviews.';
122121
COMMENT ON COLUMN proposal_review.row_id IS 'Synthetic Unique Key.';
123-
COMMENT ON COLUMN proposal_review.proposal_id IS 'The Proposal this review is for.';
124-
COMMENT ON COLUMN proposal_review.assessor IS 'Assessors Anonymized ID';
122+
COMMENT ON COLUMN proposal_review.proposal_id IS 'The Proposal id this review belongs to.';
123+
COMMENT ON COLUMN proposal_review.user_id IS 'The user id this review belongs to.';
124+
COMMENT ON COLUMN proposal_review.assessor IS 'Assessors Anonymized ID.';
125125
COMMENT ON COLUMN proposal_review.assessor_level IS 'Assessors level ID';
126-
COMMENT ON COLUMN proposal_review.reward_address IS 'Assessors reward address';
127126

128127
COMMENT ON COLUMN proposal_review.impact_alignment_rating_given IS
129-
'The numeric rating assigned to the proposal by the assessor.
130-
DEPRECATED: Only used for Vit-SS compatibility.';
128+
'The numeric rating assigned to the proposal by the assessor.';
131129
COMMENT ON COLUMN proposal_review.impact_alignment_note IS
132-
'A note about why the impact rating was given.
133-
DEPRECATED: Only used for Vit-SS compatibility.';
134-
130+
'A note about why the impact rating was given.';
135131
COMMENT ON COLUMN proposal_review.feasibility_rating_given IS
136-
'The numeric feasibility rating given.
137-
DEPRECATED: Only used for Vit-SS compatibility.';
132+
'The numeric feasibility rating given.';
138133
COMMENT ON COLUMN proposal_review.feasibility_note IS
139-
'A note about why the feasibility rating was given.
140-
DEPRECATED: Only used for Vit-SS compatibility.';
141-
134+
'A note about why the feasibility rating was given.';
142135
COMMENT ON COLUMN proposal_review.auditability_rating_given IS
143-
'The numeric auditability rating given.
144-
DEPRECATED: Only used for Vit-SS compatibility.';
136+
'The numeric auditability rating given.';
145137
COMMENT ON COLUMN proposal_review.auditability_note IS
146-
'A note about the auditability rating given.
147-
DEPRECATED: Only used for Vit-SS compatibility.';
138+
'A note about the auditability rating given.';
139+
140+
COMMENT ON COLUMN proposal_review.allocated IS
141+
'Describes if the review was part of the original reviewer allocation.
142+
';
148143

149144
COMMENT ON COLUMN proposal_review.ranking IS
150145
'Numeric Measure of quality of this review according to veteran community advisors.
File renamed without changes.
File renamed without changes.

src/event-db/migrations/V9__moderation_stage.sql

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)