Skip to content

Commit 771b5e6

Browse files
committed
three Google Photos picker endpoints (create / poll / ingest a picker-session) each repeated
1 parent 1349061 commit 771b5e6

2 files changed

Lines changed: 44 additions & 18 deletions

File tree

docs/guides/code-cleanup-issue-116.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,17 @@ and essentially all cross-`schema*` clusters. **Treat as noise.**
207207
to a `validatePrizeBody(body)` helper colocated with the prize routes. Verified: all 39 server
208208
tests pass, including the existing `prize endpoints validate and support CRUD lifecycle` test
209209
that drives invalid (400) + valid create/update through the real server.
210+
- [x]**DONE (2026-07-04) — Google Photos picker guards** (`source`/`account` cluster). The
211+
three picker endpoints (create / poll / ingest a `picker-session`) each repeated an identical
212+
"load source + assert GooglePhotos type → 404" guard and an identical "get connected account →
213+
400" guard. Extracted `loadGooglePhotoSourceOr404(sourceId, reply)` and
214+
`loadConnectedGoogleAccountOr400(reply)` (send-reply-then-`return null`, so behavior is
215+
byte-identical). The endpoint-specific `picker_session_id` checks stay inline (they differ:
216+
200 null-session vs 400 "No active picker session"). Verified: 39 server tests pass **plus** a
217+
live probe of all 7 branches — absent/wrong-type source → 404, no-account create/poll/ingest →
218+
400, and the preserved no-session branches (200 null-session, 400 "No active picker session").
219+
**Follow-up:** the same account guard also appears verbatim in 3 Google-connection routes
220+
(~3346/3366/3386); left out of this scoped change — could reuse the same helper later.
210221

211222
### 5D. Low value — likely coincidental, leave alone
212223

server/index.js

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4074,15 +4074,34 @@ fastify.delete('/api/photo-sources/:sourceId/picked/:mediaRowId', async (request
40744074
}
40754075
});
40764076

4077+
// Loads a Google Photos photo source by id. On miss (absent or wrong type),
4078+
// sends a 404 and returns null so the caller can `if (!source) return;`.
4079+
const loadGooglePhotoSourceOr404 = (sourceId, reply) => {
4080+
const source = db.prepare('SELECT * FROM photo_sources WHERE id = ?').get(sourceId);
4081+
if (!source || source.type !== 'GooglePhotos') {
4082+
reply.status(404).send({ error: 'Google Photos source not found' });
4083+
return null;
4084+
}
4085+
return source;
4086+
};
4087+
4088+
// Returns the connected Google account, or sends a 400 and returns null.
4089+
const loadConnectedGoogleAccountOr400 = (reply) => {
4090+
const account = googleConnection.getConnectedAccount(db);
4091+
if (!account) {
4092+
reply.status(400).send({ error: 'No Google account connected.' });
4093+
return null;
4094+
}
4095+
return account;
4096+
};
4097+
40774098
fastify.post('/api/photo-sources/:sourceId/picker-session', async (request, reply) => {
40784099
const { sourceId } = request.params;
40794100
try {
4080-
const source = db.prepare('SELECT * FROM photo_sources WHERE id = ?').get(sourceId);
4081-
if (!source || source.type !== 'GooglePhotos') {
4082-
return reply.status(404).send({ error: 'Google Photos source not found' });
4083-
}
4084-
const account = googleConnection.getConnectedAccount(db);
4085-
if (!account) return reply.status(400).send({ error: 'No Google account connected.' });
4101+
const source = loadGooglePhotoSourceOr404(sourceId, reply);
4102+
if (!source) return;
4103+
const account = loadConnectedGoogleAccountOr400(reply);
4104+
if (!account) return;
40864105

40874106
const session = await googlePhotosPicker.createSession(db, account.id);
40884107
db.prepare(
@@ -4105,15 +4124,13 @@ fastify.post('/api/photo-sources/:sourceId/picker-session', async (request, repl
41054124
fastify.get('/api/photo-sources/:sourceId/picker-session', async (request, reply) => {
41064125
const { sourceId } = request.params;
41074126
try {
4108-
const source = db.prepare('SELECT * FROM photo_sources WHERE id = ?').get(sourceId);
4109-
if (!source || source.type !== 'GooglePhotos') {
4110-
return reply.status(404).send({ error: 'Google Photos source not found' });
4111-
}
4127+
const source = loadGooglePhotoSourceOr404(sourceId, reply);
4128+
if (!source) return;
41124129
if (!source.picker_session_id) {
41134130
return { sessionId: null, mediaItemsSet: false };
41144131
}
4115-
const account = googleConnection.getConnectedAccount(db);
4116-
if (!account) return reply.status(400).send({ error: 'No Google account connected.' });
4132+
const account = loadConnectedGoogleAccountOr400(reply);
4133+
if (!account) return;
41174134

41184135
const session = await googlePhotosPicker.getSession(db, account.id, source.picker_session_id);
41194136
return {
@@ -4135,15 +4152,13 @@ fastify.get('/api/photo-sources/:sourceId/picker-session', async (request, reply
41354152
fastify.post('/api/photo-sources/:sourceId/picker-session/ingest', async (request, reply) => {
41364153
const { sourceId } = request.params;
41374154
try {
4138-
const source = db.prepare('SELECT * FROM photo_sources WHERE id = ?').get(sourceId);
4139-
if (!source || source.type !== 'GooglePhotos') {
4140-
return reply.status(404).send({ error: 'Google Photos source not found' });
4141-
}
4155+
const source = loadGooglePhotoSourceOr404(sourceId, reply);
4156+
if (!source) return;
41424157
if (!source.picker_session_id) {
41434158
return reply.status(400).send({ error: 'No active picker session' });
41444159
}
4145-
const account = googleConnection.getConnectedAccount(db);
4146-
if (!account) return reply.status(400).send({ error: 'No Google account connected.' });
4160+
const account = loadConnectedGoogleAccountOr400(reply);
4161+
if (!account) return;
41474162

41484163
const session = await googlePhotosPicker.getSession(db, account.id, source.picker_session_id);
41494164
if (!session.mediaItemsSet) {

0 commit comments

Comments
 (0)