Skip to content

Commit 40eca0f

Browse files
committed
eventcounter-etag-based revalidation for geodata endpoints
1 parent 535f61a commit 40eca0f

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

lib/model/query/actees.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@ const provision = (species, parent) => ({ one }) =>
1616
one(sql`insert into actees (id, species, parent) values (${uuid()}, ${species}, ${(parent == null) ? null : parent.acteeId}) returning *`)
1717
.then(construct(Actee));
1818

19-
module.exports = { provision };
19+
const getEventCount = (acteeId) => ({ oneFirst }) => oneFirst(sql`
20+
SELECT coalesce(sum(evt_cnt), 0) FROM eventcounters WHERE "acteeId" = ${acteeId}
21+
`);
22+
23+
module.exports = { provision, getEventCount };
2024

lib/resources/geo-extracts.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@
1010
const { getOrNotFound } = require('../util/promise');
1111
const { Form } = require('../model/frames');
1212
const { Sanitize } = require('../util/param-sanitize');
13-
const { isTrue, json } = require('../util/http');
13+
const { isTrue, json, withEtag } = require('../util/http');
1414

1515

1616
module.exports = (service, endpoint) => {
1717

18-
service.get('/projects/:projectId/forms/:xmlFormId/submissions.geojson', endpoint.plain(async ({ Forms, GeoExtracts }, { auth, query, params }) => {
18+
service.get('/projects/:projectId/forms/:xmlFormId/submissions.geojson', endpoint.plain(async ({ Forms, GeoExtracts, Actees }, { auth, query, params }) => {
1919

2020
const form = await Forms.getByProjectAndXmlFormId(params.projectId, params.xmlFormId, Form.WithoutDef, Form.WithoutXml)
2121
.then(getOrNotFound)
2222
.then((foundForm) => auth.canOrReject('submission.list', foundForm));
2323

24-
return GeoExtracts.getSubmissionFeatureCollectionGeoJson(
24+
const createResponse = () => GeoExtracts.getSubmissionFeatureCollectionGeoJson(
2525
form.id,
2626
Sanitize.queryParamToArray(query.fieldpath),
2727
Sanitize.queryParamToIntArray(query.submitterId, 'submitterId'),
@@ -30,22 +30,31 @@ module.exports = (service, endpoint) => {
3030
isTrue(query.deleted),
3131
Number.parseInt(query.limit, 10) || null,
3232
).then(json);
33+
34+
const acteeVersion = await Actees.getEventCount(form.acteeId);
35+
// Weak etag, as the order in the resultset is undefined.
36+
return withEtag(acteeVersion, createResponse, true);
3337
}));
3438

35-
service.get('/projects/:projectId/datasets/:datasetName/entities.geojson', endpoint.plain(async ({ Datasets, GeoExtracts }, { auth, query, params }) => {
39+
40+
service.get('/projects/:projectId/datasets/:datasetName/entities.geojson', endpoint.plain(async ({ Datasets, GeoExtracts, Actees }, { auth, query, params }) => {
3641

3742
const foundDataset = await Datasets.get(params.projectId, params.datasetName, true)
3843
.then(getOrNotFound)
3944
.then((dataset) => auth.canOrReject('entity.list', dataset));
4045

41-
return GeoExtracts.getEntityFeatureCollectionGeoJson(
46+
const createResponse = () => GeoExtracts.getEntityFeatureCollectionGeoJson(
4247
foundDataset.id,
4348
Sanitize.queryParamToIntArray(query.creatorId, 'creatorId'),
4449
Sanitize.getTSTZRangeFromQueryParams(query),
4550
Sanitize.getEntityConflictStates(query.conflict, 'conflict'),
4651
isTrue(query.deleted),
4752
Number.parseInt(query.limit, 10) || null,
4853
).then(json);
54+
55+
const acteeVersion = await Actees.getEventCount(foundDataset.acteeId);
56+
// Weak etag, as the order in the resultset is undefined.
57+
return withEtag(acteeVersion, createResponse, true);
4958
}));
5059

5160
};

0 commit comments

Comments
 (0)