diff --git a/doc/specification/entity-relationship-diagram.svg b/doc/specification/entity-relationship-diagram.svg index dbb5475..2e51c1e 100644 --- a/doc/specification/entity-relationship-diagram.svg +++ b/doc/specification/entity-relationship-diagram.svg @@ -14,7 +14,7 @@ viewBox="0 0 1052.3622 744.09448" id="svg2" version="1.1" - inkscape:version="0.91 r13725" + inkscape:version="0.92.3 (2405546, 2018-03-11)" sodipodi:docname="entity-relationship-diagram.svg"> @@ -32,7 +32,7 @@ inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" - inkscape:window-height="1058" + inkscape:window-height="1043" inkscape:window-x="1920" inkscape:window-y="0" inkscape:window-maximized="1"> @@ -66,27 +66,26 @@ y="312.36218" /> + y="335.1539" + style="font-size:20px;line-height:1.25">  YouYesYet: Entity Relationship Diagram + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:20px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold'">YouYesYet: Entity Relationship Diagram District + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial">District Addresss + sodipodi:role="line">Address Elector + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial">Elector   Authority + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial">Authority Visit + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial">Visit IssueIssueExpertise Followup FollowupFollowupAction + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial">Action @@ -528,13 +517,12 @@ id="rect4323" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> Version: 0.2Date: 20170315Author: Simon BrookeCopyright: (c) 2016 Simon Brooke for Radical Independence Campaign Introduced Visited Recorded + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Recorded Raised + style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Bold Italic';text-align:start;writing-mode:lr-tb;text-anchor:start">Raised Authenticates + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Authenticates Has + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Has About + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">About About Responded to + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Responded to Expressed + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Expressed Contains + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Contains Resides at + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Resides at Requested + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Requested Performed + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">Performed To + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start">To + y="562.36218" + style="font-size:20px;line-height:1.25">  Organiser-Organiser-ship TeamTeamMembership + id="tspan4385" + style="font-size:15px;line-height:1.25">Membership Has Has of + style="font-size:10px;line-height:1.25">of of + style="font-size:10px;line-height:1.25">of @@ -1035,16 +1002,15 @@ For + style="font-size:10px;line-height:1.25">For RoleRoleMembership + id="tspan4383" + style="font-size:15px;line-height:1.25">Membership @@ -1078,16 +1045,16 @@ x="561.61688" y="774.30139" /> Role + sodipodi:role="line" + style="font-size:15px;line-height:1.25">Role @@ -1114,28 +1081,26 @@ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> Is + style="font-size:10px;line-height:1.25">Is Includes + style="font-size:10px;line-height:1.25">Includes diff --git a/project.clj b/project.clj index 6108563..cd9bd48 100644 --- a/project.clj +++ b/project.clj @@ -53,6 +53,7 @@ [migratus-lein "0.4.2"] [org.clojars.punkisdead/lein-cucumber "1.0.5"] [lein-cljsbuild "1.1.4"] + [lein-codox "0.10.3"] [lein-uberwar "0.2.0"] [lein-bower "0.5.1"] [lein-less "1.7.5"]] diff --git a/resources/migrations/20180526162051-dwellings.down.sql b/resources/migrations/20180526162051-dwellings.down.sql new file mode 100644 index 0000000..ab91769 --- /dev/null +++ b/resources/migrations/20180526162051-dwellings.down.sql @@ -0,0 +1,8 @@ +alter table electors + add column address_id references addresses on delete no action; + +update electors + set address_id = + (select address_id + from dwellings + where dwellings.id electors.dwelling_id); diff --git a/resources/migrations/20180526162051-dwellings.up.sql b/resources/migrations/20180526162051-dwellings.up.sql new file mode 100644 index 0000000..41e1a6e --- /dev/null +++ b/resources/migrations/20180526162051-dwellings.up.sql @@ -0,0 +1,11 @@ +CREATE TABLE dwellings +( + id INT NOT NULL PRIMARY KEY, + address_id INT NOT NULL references addresses on delete no action, + sub_address VARCHAR( 32) +); + +alter table electors + add column dwelling_id int references dwellings on delete no action; + +alter table electors drop column address_id; diff --git a/resources/sql/queries.auto.sql b/resources/sql/queries.auto.sql index 5f63d1e..a80bf0f 100644 --- a/resources/sql/queries.auto.sql +++ b/resources/sql/queries.auto.sql @@ -1,6 +1,6 @@ -- File queries.sql -- autogenerated by adl.to-hugsql-queries at --- 2018-05-13T16:47:04.188Z +-- 2018-05-26T15:03:25.295Z -- See [Application Description Language](https://github.com/simon-brooke/adl). @@ -19,11 +19,13 @@ VALUES (:address, :district_id, :latitude, :longitude) +returning id -- :name create-authority! :! :n -- :doc creates a new authority record INSERT INTO authorities (id) VALUES (:id) +returning id -- :name create-canvasser! :! :n -- :doc creates a new canvasser record @@ -43,24 +45,35 @@ VALUES (:username, :email, :authority_id, :authorised) +returning id -- :name create-district! :! :n -- :doc creates a new district record INSERT INTO districts (name) VALUES (:name) +returning id + +-- :name create-dwelling! :! :n +-- :doc creates a new dwelling record +INSERT INTO dwellings (address_id, + sub-address) +VALUES (:address_id, + :sub-address) +returning id -- :name create-elector! :! :n -- :doc creates a new elector record INSERT INTO electors (name, - address_id, + dwelling_id, phone, email, gender) VALUES (:name, - :address_id, + :dwelling_id, :phone, :email, :gender) +returning id -- :name create-followupaction! :! :n -- :doc creates a new followupaction record @@ -68,37 +81,37 @@ INSERT INTO followupactions (request_id, actor, date, notes, - closed, - id) + closed) VALUES (:request_id, :actor, :date, :notes, - :closed, - :id) + :closed) +returning id -- :name create-followupmethod! :! :n -- :doc creates a new followupmethod record INSERT INTO followupmethods (id) VALUES (:id) +returning id -- :name create-followuprequest! :! :n -- :doc creates a new followuprequest record INSERT INTO followuprequests (elector_id, visit_id, issue_id, - method_id, - id) + method_id) VALUES (:elector_id, :visit_id, :issue_id, - :method_id, - :id) + :method_id) +returning id -- :name create-gender! :! :n -- :doc creates a new gender record INSERT INTO genders (id) VALUES (:id) +returning id -- :name create-intention! :! :n -- :doc creates a new intention record @@ -108,6 +121,7 @@ INSERT INTO intentions (visit_id, VALUES (:visit_id, :elector_id, :option_id) +returning Id -- :name create-issue! :! :n -- :doc creates a new issue record @@ -117,6 +131,7 @@ INSERT INTO issues (url, VALUES (:url, :current, :id) +returning id -- :name create-issueexpertis! :! :n -- :doc creates a new issueexpertis record @@ -126,16 +141,19 @@ INSERT INTO issueexpertise (canvasser_id, VALUES (:canvasser_id, :issue_id, :method_id) +returning Id -- :name create-option! :! :n -- :doc creates a new option record INSERT INTO options (id) VALUES (:id) +returning id -- :name create-role! :! :n -- :doc creates a new role record INSERT INTO roles (name) VALUES (:name) +returning id -- :name create-rolemembership! :! :n -- :doc creates a new rolemembership record @@ -143,6 +161,7 @@ INSERT INTO rolememberships (role_id, canvasser_id) VALUES (:role_id, :canvasser_id) +returning Id -- :name create-team! :! :n -- :doc creates a new team record @@ -154,6 +173,7 @@ VALUES (:name, :district_id, :latitude, :longitude) +returning id -- :name create-teammembership! :! :n -- :doc creates a new teammembership record @@ -161,6 +181,7 @@ INSERT INTO teammemberships (team_id, canvasser_id) VALUES (:team_id, :canvasser_id) +returning Id -- :name create-teamorganisership! :! :n -- :doc creates a new teamorganisership record @@ -168,6 +189,7 @@ INSERT INTO teamorganiserships (team_id, canvasser_id) VALUES (:team_id, :canvasser_id) +returning Id -- :name create-visit! :! :n -- :doc creates a new visit record @@ -177,92 +199,338 @@ INSERT INTO visits (address_id, VALUES (:address_id, :canvasser_id, :date) +returning id + +-- :name delete-address! :! :n +-- :doc updates an existing address record +DELETE FROM addresses +WHERE addresses.id = :id + +-- :name delete-authority! :! :n +-- :doc updates an existing authority record +DELETE FROM authorities +WHERE authorities.id = :id + +-- :name delete-canvasser! :! :n +-- :doc updates an existing canvasser record +DELETE FROM canvassers +WHERE canvassers.id = :id + +-- :name delete-district! :! :n +-- :doc updates an existing district record +DELETE FROM districts +WHERE districts.id = :id + +-- :name delete-dwelling! :! :n +-- :doc updates an existing dwelling record +DELETE FROM dwellings +WHERE dwellings.id = :id + +-- :name delete-elector! :! :n +-- :doc updates an existing elector record +DELETE FROM electors +WHERE electors.id = :id + +-- :name delete-followupaction! :! :n +-- :doc updates an existing followupaction record +DELETE FROM followupactions +WHERE followupactions.id = :id + +-- :name delete-followupmethod! :! :n +-- :doc updates an existing followupmethod record +DELETE FROM followupmethods +WHERE followupmethods.id = :id + +-- :name delete-followuprequest! :! :n +-- :doc updates an existing followuprequest record +DELETE FROM followuprequests +WHERE followuprequests.id = :id + +-- :name delete-gender! :! :n +-- :doc updates an existing gender record +DELETE FROM genders +WHERE genders.id = :id + +-- :name delete-intention! :! :n +-- :doc updates an existing intention record +DELETE FROM intentions +WHERE intentions.Id = :Id + +-- :name delete-issue! :! :n +-- :doc updates an existing issue record +DELETE FROM issues +WHERE issues.id = :id + +-- :name delete-issueexpertis! :! :n +-- :doc updates an existing issueexpertis record +DELETE FROM issueexpertise +WHERE issueexpertise.Id = :Id + +-- :name delete-option! :! :n +-- :doc updates an existing option record +DELETE FROM options +WHERE options.id = :id + +-- :name delete-role! :! :n +-- :doc updates an existing role record +DELETE FROM roles +WHERE roles.id = :id + +-- :name delete-rolemembership! :! :n +-- :doc updates an existing rolemembership record +DELETE FROM rolememberships +WHERE rolememberships.Id = :Id + +-- :name delete-team! :! :n +-- :doc updates an existing team record +DELETE FROM teams +WHERE teams.id = :id + +-- :name delete-teammembership! :! :n +-- :doc updates an existing teammembership record +DELETE FROM teammemberships +WHERE teammemberships.Id = :Id + +-- :name delete-teamorganisership! :! :n +-- :doc updates an existing teamorganisership record +DELETE FROM teamorganiserships +WHERE teamorganiserships.Id = :Id + +-- :name delete-visit! :! :n +-- :doc updates an existing visit record +DELETE FROM visits +WHERE visits.id = :id + +-- :name get-address :? :1 +-- :doc selects an existing address record +SELECT * FROM addresses +WHERE addresses.id = :id +ORDER BY addresses.address, + addresses.postcode, + addresses.id + +-- :name get-authority :? :1 +-- :doc selects an existing authority record +SELECT * FROM authorities +WHERE authorities.id = :id + +-- :name get-canvasser :? :1 +-- :doc selects an existing canvasser record +SELECT * FROM canvassers +WHERE canvassers.id = :id +ORDER BY canvassers.username, + canvassers.fullname, + canvassers.email, + canvassers.id + +-- :name get-district :? :1 +-- :doc selects an existing district record +SELECT * FROM districts +WHERE districts.id = :id +ORDER BY districts.name, + districts.id + +-- :name get-dwelling :? :1 +-- :doc selects an existing dwelling record +SELECT * FROM dwellings +WHERE dwellings.id = :id + +-- :name get-elector :? :1 +-- :doc selects an existing elector record +SELECT * FROM electors +WHERE electors.id = :id +ORDER BY electors.name, + electors.phone, + electors.email, + electors.id + +-- :name get-followupaction :? :1 +-- :doc selects an existing followupaction record +SELECT * FROM followupactions +WHERE followupactions.id = :id + +-- :name get-followupmethod :? :1 +-- :doc selects an existing followupmethod record +SELECT * FROM followupmethods +WHERE followupmethods.id = :id + +-- :name get-followuprequest :? :1 +-- :doc selects an existing followuprequest record +SELECT * FROM followuprequests +WHERE followuprequests.id = :id + +-- :name get-gender :? :1 +-- :doc selects an existing gender record +SELECT * FROM genders +WHERE genders.id = :id + +-- :name get-intention :? :1 +-- :doc selects an existing intention record +SELECT * FROM intentions +WHERE intentions.Id = :Id + +-- :name get-issue :? :1 +-- :doc selects an existing issue record +SELECT * FROM issues +WHERE issues.id = :id + +-- :name get-issueexpertis :? :1 +-- :doc selects an existing issueexpertis record +SELECT * FROM issueexpertise +WHERE issueexpertise.Id = :Id + +-- :name get-option :? :1 +-- :doc selects an existing option record +SELECT * FROM options +WHERE options.id = :id + +-- :name get-role :? :1 +-- :doc selects an existing role record +SELECT * FROM roles +WHERE roles.id = :id +ORDER BY roles.name, + roles.id + +-- :name get-rolemembership :? :1 +-- :doc selects an existing rolemembership record +SELECT * FROM rolememberships +WHERE rolememberships.Id = :Id + +-- :name get-team :? :1 +-- :doc selects an existing team record +SELECT * FROM teams +WHERE teams.id = :id +ORDER BY teams.name, + teams.id + +-- :name get-teammembership :? :1 +-- :doc selects an existing teammembership record +SELECT * FROM teammemberships +WHERE teammemberships.Id = :Id + +-- :name get-teamorganisership :? :1 +-- :doc selects an existing teamorganisership record +SELECT * FROM teamorganiserships +WHERE teamorganiserships.Id = :Id + +-- :name get-visit :? :1 +-- :doc selects an existing visit record +SELECT * FROM visits +WHERE visits.id = :id -- :name list-addresses :? :* -- :doc lists all existing address records SELECT * FROM addresses ORDER BY addresses.address, - addresses.postcode + addresses.postcode, + addresses.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name list-addresses-by-district :? :* -- :doc lists all existing address records related to a given district -SELECT * +SELECT * FROM addresses WHERE addresses.district_id = :id ORDER BY addresses.address, - addresses.postcode + addresses.postcode, + addresses.id + +-- :name list-authorities :? :* +-- :doc lists all existing authority records +SELECT * FROM authorities +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name list-canvassers :? :* -- :doc lists all existing canvasser records SELECT * FROM canvassers ORDER BY canvassers.username, canvassers.fullname, - canvassers.email + canvassers.email, + canvassers.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name list-canvassers-by-address :? :* -- :doc lists all existing canvasser records related to a given address -SELECT * +SELECT * FROM canvassers WHERE canvassers.address_id = :id ORDER BY canvassers.username, canvassers.fullname, - canvassers.email + canvassers.email, + canvassers.id -- :name list-canvassers-by-authority :? :* -- :doc lists all existing canvasser records related to a given authority -SELECT * +SELECT * FROM canvassers WHERE canvassers.authority_id = :id ORDER BY canvassers.username, canvassers.fullname, - canvassers.email + canvassers.email, + canvassers.id -- :name list-canvassers-by-elector :? :* -- :doc lists all existing canvasser records related to a given elector -SELECT * +SELECT * FROM canvassers WHERE canvassers.elector_id = :id ORDER BY canvassers.username, canvassers.fullname, - canvassers.email + canvassers.email, + canvassers.id -- :name list-districts :? :* -- :doc lists all existing district records SELECT * FROM districts -ORDER BY districts.name +ORDER BY districts.name, + districts.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") +-- :name list-dwellings :? :* +-- :doc lists all existing dwelling records +SELECT * FROM dwellings +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-dwellings-by-addres :? :* +-- :doc lists all existing dwelling records related to a given addres +SELECT * +FROM dwellings +WHERE dwellings.address_id = :id + -- :name list-electors :? :* -- :doc lists all existing elector records SELECT * FROM electors ORDER BY electors.name, electors.phone, - electors.email + electors.email, + electors.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") --- :name list-electors-by-address :? :* --- :doc lists all existing elector records related to a given address -SELECT * +-- :name list-electors-by-dwelling :? :* +-- :doc lists all existing elector records related to a given dwelling +SELECT * FROM electors -WHERE electors.address_id = :id +WHERE electors.dwelling_id = :id ORDER BY electors.name, electors.phone, - electors.email + electors.email, + electors.id -- :name list-electors-by-gender :? :* -- :doc lists all existing elector records related to a given gender -SELECT * +SELECT * FROM electors WHERE electors.gender = :id ORDER BY electors.name, electors.phone, - electors.email + electors.email, + electors.id -- :name list-followupactions :? :* -- :doc lists all existing followupaction records @@ -272,42 +540,195 @@ SELECT * FROM followupactions -- :name list-followupactions-by-canvasser :? :* -- :doc lists all existing followupaction records related to a given canvasser -SELECT * +SELECT * FROM followupactions WHERE followupactions.actor = :id -- :name list-followupactions-by-followuprequest :? :* -- :doc lists all existing followupaction records related to a given followuprequest -SELECT * +SELECT * FROM followupactions WHERE followupactions.request_id = :id +-- :name list-followupmethods :? :* +-- :doc lists all existing followupmethod records +SELECT * FROM followupmethods +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-followuprequests :? :* +-- :doc lists all existing followuprequest records +SELECT * FROM followuprequests +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-followuprequests-by-elector :? :* +-- :doc lists all existing followuprequest records related to a given elector +SELECT * +FROM followuprequests +WHERE followuprequests.elector_id = :id + +-- :name list-followuprequests-by-followupmethod :? :* +-- :doc lists all existing followuprequest records related to a given followupmethod +SELECT * +FROM followuprequests +WHERE followuprequests.method_id = :id + +-- :name list-followuprequests-by-issue :? :* +-- :doc lists all existing followuprequest records related to a given issue +SELECT * +FROM followuprequests +WHERE followuprequests.issue_id = :id + +-- :name list-followuprequests-by-visit :? :* +-- :doc lists all existing followuprequest records related to a given visit +SELECT * +FROM followuprequests +WHERE followuprequests.visit_id = :id + +-- :name list-genders :? :* +-- :doc lists all existing gender records +SELECT * FROM genders +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-intentions :? :* +-- :doc lists all existing intention records +SELECT * FROM intentions +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-intentions-by-elector :? :* +-- :doc lists all existing intention records related to a given elector +SELECT * +FROM intentions +WHERE intentions.elector_id = :id + +-- :name list-intentions-by-option :? :* +-- :doc lists all existing intention records related to a given option +SELECT * +FROM intentions +WHERE intentions.option_id = :id + +-- :name list-intentions-by-visit :? :* +-- :doc lists all existing intention records related to a given visit +SELECT * +FROM intentions +WHERE intentions.visit_id = :id + +-- :name list-issueexpertise :? :* +-- :doc lists all existing issueexpertis records +SELECT * FROM issueexpertise +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-issueexpertise-by-canvasser :? :* +-- :doc lists all existing issueexpertis records related to a given canvasser +SELECT * +FROM issueexpertise +WHERE issueexpertise.canvasser_id = :id + +-- :name list-issueexpertise-by-followupmethod :? :* +-- :doc lists all existing issueexpertis records related to a given followupmethod +SELECT * +FROM issueexpertise +WHERE issueexpertise.method_id = :id + +-- :name list-issueexpertise-by-issue :? :* +-- :doc lists all existing issueexpertis records related to a given issue +SELECT * +FROM issueexpertise +WHERE issueexpertise.issue_id = :id + -- :name list-issues :? :* -- :doc lists all existing issue records SELECT * FROM issues --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") +-- :name list-options :? :* +-- :doc lists all existing option records +SELECT * FROM options +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-rolememberships :? :* +-- :doc lists all existing rolemembership records +SELECT * FROM rolememberships +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-rolememberships-by-canvasser :? :* +-- :doc lists all existing rolemembership records related to a given canvasser +SELECT * +FROM rolememberships +WHERE rolememberships.canvasser_id = :id + +-- :name list-rolememberships-by-role :? :* +-- :doc lists all existing rolemembership records related to a given role +SELECT * +FROM rolememberships +WHERE rolememberships.role_id = :id + -- :name list-roles :? :* -- :doc lists all existing role records SELECT * FROM roles -ORDER BY roles.name +ORDER BY roles.name, + roles.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") +-- :name list-teammemberships :? :* +-- :doc lists all existing teammembership records +SELECT * FROM teammemberships +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-teammemberships-by-canvasser :? :* +-- :doc lists all existing teammembership records related to a given canvasser +SELECT * +FROM teammemberships +WHERE teammemberships.canvasser_id = :id + +-- :name list-teammemberships-by-team :? :* +-- :doc lists all existing teammembership records related to a given team +SELECT * +FROM teammemberships +WHERE teammemberships.team_id = :id + +-- :name list-teamorganiserships :? :* +-- :doc lists all existing teamorganisership records +SELECT * FROM teamorganiserships +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name list-teamorganiserships-by-canvasser :? :* +-- :doc lists all existing teamorganisership records related to a given canvasser +SELECT * +FROM teamorganiserships +WHERE teamorganiserships.canvasser_id = :id + +-- :name list-teamorganiserships-by-team :? :* +-- :doc lists all existing teamorganisership records related to a given team +SELECT * +FROM teamorganiserships +WHERE teamorganiserships.team_id = :id + -- :name list-teams :? :* -- :doc lists all existing team records SELECT * FROM teams -ORDER BY teams.name +ORDER BY teams.name, + teams.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name list-teams-by-district :? :* -- :doc lists all existing team records related to a given district -SELECT * +SELECT * FROM teams WHERE teams.district_id = :id -ORDER BY teams.name +ORDER BY teams.name, + teams.id -- :name list-visits :? :* -- :doc lists all existing visit records @@ -317,67 +738,79 @@ SELECT * FROM visits -- :name list-visits-by-address :? :* -- :doc lists all existing visit records related to a given address -SELECT * +SELECT * FROM visits WHERE visits.address_id = :id -- :name list-visits-by-canvasser :? :* -- :doc lists all existing visit records related to a given canvasser -SELECT * +SELECT * FROM visits WHERE visits.canvasser_id = :id -- :name search-strings-address :? :1 -- :doc selects existing address records having any string field matching `:pattern` by substring match SELECT * FROM addresses -WHERE +WHERE address LIKE '%:pattern%' OR phone LIKE '%:pattern%' ORDER BY addresses.address, - addresses.postcode + addresses.postcode, + addresses.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name search-strings-canvasser :? :1 -- :doc selects existing canvasser records having any string field matching `:pattern` by substring match SELECT * FROM canvassers -WHERE +WHERE username LIKE '%:pattern%' OR fullname LIKE '%:pattern%' OR phone LIKE '%:pattern%' OR email LIKE '%:pattern%' ORDER BY canvassers.username, canvassers.fullname, - canvassers.email + canvassers.email, + canvassers.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name search-strings-district :? :1 -- :doc selects existing district records having any string field matching `:pattern` by substring match SELECT * FROM districts -WHERE +WHERE name LIKE '%:pattern%' -ORDER BY districts.name +ORDER BY districts.name, + districts.id +--~ (if (:offset params) "OFFSET :offset ") +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") + +-- :name search-strings-dwelling :? :1 +-- :doc selects existing dwelling records having any string field matching `:pattern` by substring match +SELECT * FROM dwellings +WHERE +sub-address LIKE '%:pattern%' --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name search-strings-elector :? :1 -- :doc selects existing elector records having any string field matching `:pattern` by substring match SELECT * FROM electors -WHERE +WHERE name LIKE '%:pattern%' OR phone LIKE '%:pattern%' OR email LIKE '%:pattern%' ORDER BY electors.name, electors.phone, - electors.email + electors.email, + electors.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name search-strings-issue :? :1 -- :doc selects existing issue records having any string field matching `:pattern` by substring match SELECT * FROM issues -WHERE +WHERE url LIKE '%:pattern%' --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") @@ -385,17 +818,19 @@ url LIKE '%:pattern%' -- :name search-strings-role :? :1 -- :doc selects existing role records having any string field matching `:pattern` by substring match SELECT * FROM roles -WHERE +WHERE name LIKE '%:pattern%' -ORDER BY roles.name +ORDER BY roles.name, + roles.id --~ (if (:offset params) "OFFSET :offset ") --~ (if (:limit params) "LIMIT :limit" "LIMIT 100") -- :name search-strings-team :? :1 -- :doc selects existing team records having any string field matching `:pattern` by substring match SELECT * FROM teams -WHERE +WHERE name LIKE '%:pattern%' -ORDER BY teams.name +ORDER BY teams.name, + teams.id --~ (if (:offset params) "OFFSET :offset ") ---~ (if (:limit params) "LIMIT :limit" "LIMIT 100") \ No newline at end of file +--~ (if (:limit params) "LIMIT :limit" "LIMIT 100") diff --git a/src/clj/youyesyet/routes/auto_json_routes.clj b/src/clj/youyesyet/routes/auto_json_routes.clj index 8d3d707..c9732cd 100644 --- a/src/clj/youyesyet/routes/auto_json_routes.clj +++ b/src/clj/youyesyet/routes/auto_json_routes.clj @@ -11,7 +11,7 @@ (declare - create-addresse + create-address create-authority create-canvasser create-district @@ -30,7 +30,7 @@ create-teammembership create-teamorganisership create-visit - delete-addresse + delete-address delete-authority delete-canvasser delete-district @@ -41,7 +41,7 @@ delete-issue delete-option delete-visit - get-addresse + get-address get-authority get-canvasser get-district @@ -61,7 +61,7 @@ list-canvassers-by-elector list-districts list-electors - list-electors-by-addresse + list-electors-by-address list-followupactions list-followupactions-by-canvasser list-followupactions-by-followuprequest @@ -96,9 +96,9 @@ list-teams list-teams-by-district list-visits - list-visits-by-addresse + list-visits-by-address list-visits-by-canvasser - update-addresse + update-address update-canvasser update-district update-elector @@ -110,7 +110,7 @@ (defroutes auto-rest-routes - (POST "/json/auto/create-addresse" request (create-addresse request)) + (POST "/json/auto/create-addresse" request (create-address request)) (POST "/json/auto/create-authority" request @@ -162,7 +162,7 @@ request (create-teamorganisership request)) (POST "/json/auto/create-visit" request (create-visit request)) - (POST "/json/auto/delete-addresse" request (delete-addresse request)) + (POST "/json/auto/delete-addresse" request (delete-address request)) (POST "/json/auto/delete-authority" request @@ -382,10 +382,10 @@ (defn - create-addresse + create-address "Auto-generated method to insert one record to the addresses table. Expects the following key(s) to be present in `params`: (:id :address :postcode :phone :district_id :latitude :longitude). Returns a map containing the keys (:id) identifying the record created." [{:keys [params]}] - (do (db/create-addresse! params))) + (do (db/create-address! params))) (defn @@ -515,10 +515,10 @@ (defn - delete-addresse + delete-address "Auto-generated method to delete one record from the addresses table. Expects the following key(s) to be present in `params`: (:id)." [{:keys [params]}] - (do (db/delete-addresse! params)) + (do (db/delete-address! params)) (response/found "/")) @@ -970,10 +970,10 @@ (defn - update-addresse + update-address "Auto-generated method to update one record in the addresses table. Expects the following key(s) to be present in `params`: (:address :district_id :id :latitude :longitude :phone :postcode)." [{:keys [params]}] - (do (db/update-addresse! params)) + (do (db/update-address! params)) (response/found "/")) diff --git a/youyesyet.adl.xml b/youyesyet.adl.xml new file mode 100644 index 0000000..54e6214 --- /dev/null +++ b/youyesyet.adl.xml @@ -0,0 +1,392 @@ + + + + + A web-app intended to be used by canvassers campaigning for a 'Yes' vote in the second independence referendum. + + The web-app will be delivered to canvassers out knocking doors primarily through an HTML5/React single-page app designed to work on a mobile phone; it's possible that someone else may do an Android of iPhone native app to address the same back end but at present I have no plans for this. + + There must also be an administrative interface through which privileged users can set the system up and authorise canvassers, and a 'followup' interface through which issue-expert specialist canvassers can address particular electors' queries. + + + + + + + + See + https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/488478/Bulk_Data_Transfer_-_additional_validation_valid_from_12_November_2015.pdf, + section 3 + A valid postcode. + + + All users + + + All users of the canvasser app Able to read and add canvassing data in a limited + radius around their current position. + + + Organisers of canvassing teams Able to see and modify data on the canvassers in + the team(s) they organise; able to add canvassers to their team; able to update canvassers in + their team, including resetting passwords and locking accounts; able to see canvass data over + the whole area in which their team operates. + + + People expert on particular issues. Able to read followup requests, and the electors to which they + relate; able to access (read/write) the issues wiki; able to write followuop action records. + + + + Users entitled to see an overview of the canvassing data collected. Able to read canvassing data over the whole map, including historical + data. + + + Users responsible for determining what issues should be current at any time. + Able to set current issues; able to add issues. + + + Able to read and update canvasser records, team membership records, team + organisership records, issue expertise records; able to add and update reference data + generally. + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Issues believed to be of interest to electors, about which they may have questions. + + + + + + + + + + + + + + + + Link table. + + + + + + + + + + + + Primary users of the system: those actually interviewing electors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + But only their own record + + + But only canvassers in their own team. + + + All canvassers + + + + Requests for a followup with an issue expert + + + + + + + + + + + + + + + + + + + + Link table + + + + + + + + + A role (essentially, the same as a group, but application layer rather than database layer) of which a user may be a member. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + But only their own group(s) + + + All groups + + + + Electoral districts + + + + + + + + + + + + + Link table + + + + + + + + + Actions taken on followup requests. + + + + + + + + + + + + + + + + + + + + + + + But only for electors in their immediate vicinity + + + + + Link table + + + + + + + + + + + + Options in the election or referendum being canvassed on + + + + + + + + Link table + + + + + + + + + + + + + + + diff --git a/youyesyet.canonical.adl.xml b/youyesyet.canonical.adl.xml index 0fa1f0a..4bdbeee 100644 --- a/youyesyet.canonical.adl.xml +++ b/youyesyet.canonical.adl.xml @@ -1,11 +1,33 @@ - + + + + + A web-app intended to be used by canvassers campaigning for a 'Yes' vote in the second independence referendum. + + The web-app will be delivered to canvassers out knocking doors primarily through an HTML5/React single-page app designed to work on a mobile phone; it's possible that someone else may do an Android of iPhone native app to address the same back end but at present I have no plans for this. + + There must also be an administrative interface through which privileged users can set the system up and authorise canvassers, and a 'followup' interface through which issue-expert specialist canvassers can address particular electors' queries. + - + See https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/488478/Bulk_Data_Transfer_-_additional_validation_valid_from_12_November_2015.pdf, section 3 @@ -18,7 +40,7 @@ All users of the canvasser app Able to read and add canvassing data in a limited radius around their current position. - + Organisers of canvassing teams Able to see and modify data on the canvassers in the team(s) they organise; able to add canvassers to their team; able to update canvassers in their team, including resetting passwords and locking accounts; able to see canvass data over @@ -42,30 +64,32 @@ organisership records, issue expertise records; able to add and update reference data generally. - + - + - - + + - + - + - - + + @@ -73,9 +97,35 @@ - -
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + @@ -96,16 +146,19 @@ - + dwe - -
+ +
+ @@ -124,6 +177,9 @@ + @@ -131,6 +187,9 @@ + Issues believed to be of interest to electors, about which they may have questions. @@ -144,21 +203,42 @@ - -
+ +
- + + Link table. + + + + + Auto-generated abstract primary key + + + - + + + + + + + + + Primary users of the system: those actually interviewing electors. @@ -184,7 +264,7 @@ - + @@ -200,35 +280,59 @@ All canvassers + Requests for a followup with an issue expert - + - + - + - + - + + Link table + + + + + Auto-generated abstract primary key + + + + + + + + + + + A role (essentially, the same as a group, but application layer rather than database layer) of which a user may be a member. @@ -240,8 +344,10 @@ + - Teams of canvassers who work together under common leadership. @@ -267,6 +373,9 @@ All groups + Electoral districts @@ -280,19 +389,40 @@ - + + Link table + + + + + Auto-generated abstract primary key + + + + + + + + + + + Actions taken on followup requests. - + @@ -317,18 +447,39 @@ - + + Link table - + + + + + Auto-generated abstract primary key + + + + - + + + + + + + + + Options in the election or referendum being canvassed on @@ -337,18 +488,39 @@ - + + Link table + + + + + Auto-generated abstract primary key + + + + + + + + + + + - +