Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
525 changes: 0 additions & 525 deletions openapi/frigg-scale-test-mock-crm.yaml

This file was deleted.

1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions packages/v1-ready/frigg-scale-test/FUTURE_ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Future Roadmap

This document tracks features that were part of the original specification but have been commented out or removed to simplify the initial implementation. These may be added back in future iterations.

## Removed Features

### Activities
- **listActivities**: List activities with filtering by type, contactId, and delta sync
- **createActivity**: Create new activities (phone calls, emails, SMS)
- Activity types supported: phone_call, email, sms

### Bulk Export Operations
- **requestContactsExport**: Request bulk export of contacts in NDJSON/CSV format
- **requestActivitiesExport**: Request bulk export of activities
- **getExportJob**: Poll export job status and retrieve download URL

### Configuration Management
- **getConfig**: Retrieve per-account configuration (page size, rate limits, latency simulation, error rates)
- **putConfig**: Update per-account configuration for testing different scenarios

### Mutation Tracking
- **Hybrid change-log**: Track create/update/delete operations on contacts and activities
- Persistent state layer for testing delta sync and webhook simulations

## Rationale for Removal

The current focus is on providing a simple, deterministic synthetic data generator for contact scale testing. The above features added complexity around:
- HTTP communication layers
- State persistence and management
- Multiple entity types
- Advanced testing scenarios

These can be incrementally added back as needed for more sophisticated testing scenarios.

## Implementation Notes for Future

When re-implementing these features, consider:
1. The lambda handler in `/services/frigg-scale-test-lambda` may need updates
2. OpenAPI spec in `frigg-scale-test-mock-crm.yaml` can be expanded
3. Maintain deterministic generation for all synthetic data
4. Consider memory efficiency for bulk operations

145 changes: 145 additions & 0 deletions packages/v1-ready/frigg-scale-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Frigg Scale Test API Module

A synthetic data generator for scale testing that deterministically generates up to 3 million contacts without requiring external services or data storage.

## Features

- **Deterministic Generation**: Same input parameters always produce the same contacts
- **Memory Efficient**: Generates contacts on-the-fly during pagination without storing them in memory
- **Scalable**: Supports up to 3 million unique contacts per account
- **Predictable Pagination**: Cursor-based pagination with configurable page sizes
- **No Dependencies**: No external services or databases required

## Installation

```bash
npm install @friggframework/api-module-frigg-scale-test
```

## Usage

```javascript
const { Api, Definition, Config } = require('@friggframework/api-module-frigg-scale-test');

// Initialize the API
const api = new Api();

// Health check
const health = await api.health();
console.log(health); // { ok: true }

// List contacts with pagination
const page1 = await api.listContacts({
accountId: 'demo',
limit: 100
});

console.log(page1.items.length); // 100
console.log(page1.nextCursor); // '100' (offset for next page)

// Get next page
const page2 = await api.listContacts({
accountId: 'demo',
limit: 100,
cursor: page1.nextCursor
});

// Filter by updatedSince
const recentContacts = await api.listContacts({
accountId: 'demo',
limit: 100,
updatedSince: '2024-01-01T00:00:00Z'
});
```

## API Methods

### `health()`

Returns a health check status.

**Returns:** `Promise<{ ok: boolean }>`

### `listContacts(params)`

Generates and returns a page of synthetic contacts.

**Parameters:**
- `accountId` (string, required): Account identifier used for deterministic generation
- `limit` (number, optional): Number of contacts to return (default: 100, max: 1000)
- `cursor` (string, optional): Pagination cursor (offset)
- `updatedSince` (string, optional): ISO 8601 timestamp to filter contacts

**Returns:** `Promise<{ items: Contact[], nextCursor: string | null }>`

**Contact Schema:**
```typescript
{
id: string;
email: string;
phone: string;
firstName: string;
lastName: string;
company: string;
address: string;
city: string;
region: string;
country: string;
postalCode: string;
updatedAt: string; // ISO 8601
payload: {
generatedIndex: number;
accountId: string;
};
}
```

## Configuration

The module exports a `Config` object with metadata:

```javascript
{
"name": "frigg-scale-test",
"label": "Frigg Scale Test",
"description": "Mock CRM for scale testing with deterministic synthetic data"
}
```

## Definition

The module exports a Frigg Framework `Definition` object for integration with the Frigg framework's authentication and module system.

## Deterministic Generation

All contacts are generated deterministically using a seeded random number generator. The seed is derived from the `accountId` and contact index, ensuring:

1. Same `accountId` + `index` always produces the same contact
2. Different `accountId` values produce different contact sets
3. Contacts remain unique across the full 3 million record range

## Future Features

See [FUTURE_ROADMAP.md](./FUTURE_ROADMAP.md) for planned features including:
- Activities (phone calls, emails, SMS)
- Bulk export operations
- Configuration management for testing scenarios
- Mutation tracking for delta sync testing

## Development

```bash
# Build
npm run build

# Test
npm test

# Lint
npm run lint
```

## License

MIT

6 changes: 6 additions & 0 deletions packages/v1-ready/frigg-scale-test/defaultConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "frigg-scale-test",
"label": "Frigg Scale Test",
"description": "Mock CRM for scale testing with deterministic synthetic data"
}

109 changes: 109 additions & 0 deletions packages/v1-ready/frigg-scale-test/frigg-scale-test-mock-crm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
openapi: 3.0.3
info:
title: Frigg Scale Test Mock CRM
version: 0.1.0
description: Synthetic data generator for Frigg scale testing with deterministic contact generation (up to 3M records)
servers:
- url: https://mock.local
tags:
- name: Health
- name: Contacts
paths:
/health:
get:
tags: [Health]
summary: Health check
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Health"
/contacts:
get:
tags: [Contacts]
summary: List contacts (cursor pagination, deterministically generated)
parameters:
- in: query
name: accountId
required: true
schema:
type: string
- in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 1000
default: 100
- in: query
name: cursor
schema:
type: string
description: Offset cursor for pagination
- in: query
name: updatedSince
schema:
type: string
format: date-time
description: Filter contacts updated after this timestamp
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/ContactPage"
components:
schemas:
Health:
type: object
properties:
ok:
type: boolean
Contact:
type: object
required: [id, email, updatedAt]
properties:
id:
type: string
email:
type: string
format: email
phone:
type: string
firstName:
type: string
lastName:
type: string
company:
type: string
address:
type: string
city:
type: string
region:
type: string
country:
type: string
postalCode:
type: string
updatedAt:
type: string
format: date-time
payload:
type: object
additionalProperties: true
ContactPage:
type: object
required: [items]
properties:
items:
type: array
items:
$ref: "#/components/schemas/Contact"
nextCursor:
type: string
nullable: true

Loading
Loading