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
+
+
+
+
+
+
+
+
+
+
+
-
+