Skip to content

Commit

Permalink
fix(api): get records filter should accept uppercase and combined (#3460
Browse files Browse the repository at this point in the history
)

## Changes

- `GET /records` filter param should accept uppercase and combined
I missed that when checking the openapi spec, it's not documented there
but it's in the node-client. e.g: `ADDED,updated`


```
curl --request GET \
  --url 'http://localhost:3003/records?model=LastSyncDate&limit=100&filter=UPDATED%2Cadded' \
  --header 'Authorization: ' \
  --header 'Connection-Id: 025d9a38-f31c-4a64-b034-57a425761a90' \
  --header 'Provider-Config-Key: unauthenticated' \
  --header 'content-type: application/json'
```
  • Loading branch information
bodinsamuel authored Feb 5, 2025
1 parent 62fbacd commit 698ecc0
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
13 changes: 11 additions & 2 deletions packages/records/lib/models/records.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc.js';
import { db } from '../db/client.js';
import type { FormattedRecord, FormattedRecordWithMetadata, GetRecordsResponse, LastAction, RecordCount, ReturnedRecord, UpsertSummary } from '../types.js';
import type {
CombinedFilterAction,
FormattedRecord,
FormattedRecordWithMetadata,
GetRecordsResponse,
LastAction,
RecordCount,
ReturnedRecord,
UpsertSummary
} from '../types.js';
import { decryptRecordData, encryptRecords } from '../utils/encryption.js';
import { RECORDS_TABLE, RECORD_COUNTS_TABLE } from '../constants.js';
import { removeDuplicateKey, getUniqueId } from '../helpers/uniqueKey.js';
Expand Down Expand Up @@ -53,7 +62,7 @@ export async function getRecords({
model: string;
modifiedAfter?: string | undefined;
limit?: number | string | undefined;
filter?: LastAction | undefined;
filter?: CombinedFilterAction | LastAction | undefined;
cursor?: string | undefined;
}): Promise<Result<GetRecordsResponse>> {
try {
Expand Down
1 change: 1 addition & 0 deletions packages/records/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type ReturnedRecord = {
} & Record<string, RecordValue> & { id: string };

export type LastAction = 'ADDED' | 'UPDATED' | 'DELETED' | 'added' | 'updated' | 'deleted';
export type CombinedFilterAction = `${LastAction},${LastAction}`;

interface RecordMetadata {
first_seen_at: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,84 @@ describe(`GET ${route}`, () => {
]
});
});

it('should filter', async () => {
const { env } = await seeders.seedAccountEnvAndUser();
const conn = await seeders.createConnectionSeed({ env, provider: 'github' });

await records.upsert({
records: format
.formatRecords({
data: [
{ id: 'record1', foo: 'bar' },
{ id: 'record2', foo: 'bar' },
{ id: 'record3', foo: 'bar' }
],
syncId: '695a23e3-64aa-4978-87bf-2cfc9044e675',
syncJobId: 1,
connectionId: conn.id!,
model: 'Ticket'
})
.unwrap(),
connectionId: conn.id!,
environmentId: env.id,
model: 'Ticket'
});

// Added
const resAdded = await api.fetch(route, {
method: 'GET',
token: env.secret_key,
query: { model: 'Ticket', filter: 'added' },
headers: { 'connection-id': conn.connection_id, 'provider-config-key': 'github' }
});
isSuccess(resAdded.json);
expect(resAdded.json.records).toHaveLength(3);

await records.upsert({
records: format
.formatRecords({
data: [{ id: 'record1', foo: 'bar2' }],
syncId: '695a23e3-64aa-4978-87bf-2cfc9044e675',
syncJobId: 2,
connectionId: conn.id!,
model: 'Ticket'
})
.unwrap(),
connectionId: conn.id!,
environmentId: env.id,
model: 'Ticket'
});

// Updated
const resUpdated = await api.fetch(route, {
method: 'GET',
token: env.secret_key,
query: { model: 'Ticket', filter: 'UPDATED' },
headers: { 'connection-id': conn.connection_id, 'provider-config-key': 'github' }
});
isSuccess(resUpdated.json);
expect(resUpdated.json.records).toHaveLength(1);

// Deleted
const resDeleted = await api.fetch(route, {
method: 'GET',
token: env.secret_key,
query: { model: 'Ticket', filter: 'deleted' },
headers: { 'connection-id': conn.connection_id, 'provider-config-key': 'github' }
});
isSuccess(resDeleted.json);
expect(resDeleted.json.records).toHaveLength(0);

// Multiple filters
const resMultiple = await api.fetch(route, {
method: 'GET',
token: env.secret_key,
query: { model: 'Ticket', filter: 'added,UPDATED' },
headers: { 'connection-id': conn.connection_id, 'provider-config-key': 'github' }
});

isSuccess(resMultiple.json);
expect(resMultiple.json.records).toHaveLength(3);
});
});
7 changes: 6 additions & 1 deletion packages/server/lib/controllers/records/getRecords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export const validationQuery = z
delta: z.string().datetime().optional(),
modified_after: z.string().datetime().optional(),
limit: z.coerce.number().min(1).max(10000).default(100).optional(),
filter: z.enum(['added', 'updated', 'deleted']).optional(),
filter: z
.string()
.transform((value) => value.split(','))
.pipe(z.array(z.enum(['added', 'updated', 'deleted', 'ADDED', 'UPDATED', 'DELETED'])))
.transform<GetPublicRecords['Querystring']['filter']>((value) => value.join(',') as GetPublicRecords['Querystring']['filter'])
.optional(),
cursor: z.string().min(1).max(1000).optional()
})
.strict();
Expand Down
3 changes: 2 additions & 1 deletion packages/types/lib/record/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ApiError, Endpoint } from '../api';

export type RecordLastAction = 'ADDED' | 'UPDATED' | 'DELETED' | 'added' | 'updated' | 'deleted';
export type CombinedFilterAction = `${RecordLastAction},${RecordLastAction}`;

export interface RecordMetadata {
first_seen_at: string;
Expand Down Expand Up @@ -33,7 +34,7 @@ export type GetPublicRecords = Endpoint<{
delta?: string | undefined;
modified_after?: string | undefined;
limit?: number | undefined;
filter?: 'added' | 'updated' | 'deleted' | undefined;
filter?: RecordLastAction | CombinedFilterAction | undefined;
cursor?: string | undefined;
};
Success: {
Expand Down

0 comments on commit 698ecc0

Please # to comment.