Skip to content

Commit 822000f

Browse files
authored
squash (#352)
1 parent 5024aac commit 822000f

109 files changed

Lines changed: 2000 additions & 1683 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/dashboard/e2e/pipeline-create.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ test('full pipeline creation flow: source → discover → streams → destinati
2929

3030
// Expand Payments and select a stream
3131
await page.getByText('Payments').click()
32-
const chargesCheckbox = page.locator('label').filter({ hasText: 'charges' }).locator('input')
32+
const chargesCheckbox = page.locator('label').filter({ hasText: 'charge' }).locator('input')
3333
await chargesCheckbox.check()
3434

3535
// Expand Customers and select
3636
await page.getByText('Customers').click()
37-
const customersCheckbox = page.locator('label').filter({ hasText: 'customers' }).locator('input')
37+
const customersCheckbox = page.locator('label').filter({ hasText: 'customer' }).locator('input')
3838
await customersCheckbox.check()
3939

4040
// Verify search works
@@ -57,8 +57,8 @@ test('full pipeline creation flow: source → discover → streams → destinati
5757
await expect(page.getByText('stripe').first()).toBeVisible()
5858
await expect(page.getByText('postgres').first()).toBeVisible()
5959
await expect(page.getByText('2 tables selected')).toBeVisible()
60-
await expect(page.getByText('charges')).toBeVisible()
61-
await expect(page.getByText('customers')).toBeVisible()
60+
await expect(page.getByText('charge')).toBeVisible()
61+
await expect(page.getByText('customer')).toBeVisible()
6262

6363
// The "Start sync" button should be visible
6464
await expect(page.getByRole('button', { name: /start sync/i })).toBeVisible()

apps/dashboard/src/lib/stream-groups.test.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@ function stream(name: string): CatalogStream {
88
describe('groupStreams', () => {
99
it('groups payment-related streams together', () => {
1010
const streams = [
11-
stream('payment_intents'),
12-
stream('payment_methods'),
13-
stream('charges'),
14-
stream('refunds'),
11+
stream('payment_intent'),
12+
stream('payment_method'),
13+
stream('charge'),
14+
stream('refund'),
1515
]
1616
const groups = groupStreams(streams)
1717
const payments = groups.find((g) => g.name === 'Payments')
1818
expect(payments).toBeDefined()
1919
expect(payments!.streams.map((s) => s.name)).toEqual(
20-
expect.arrayContaining(['payment_intents', 'payment_methods', 'charges', 'refunds'])
20+
expect.arrayContaining(['payment_intent', 'payment_method', 'charge', 'refund'])
2121
)
2222
})
2323

2424
it('groups billing-related streams together', () => {
2525
const streams = [
26-
stream('subscriptions'),
27-
stream('subscription_schedules'),
28-
stream('invoices'),
29-
stream('prices'),
30-
stream('plans'),
31-
stream('coupons'),
32-
stream('credit_notes'),
26+
stream('subscription'),
27+
stream('subscription_schedule'),
28+
stream('invoice'),
29+
stream('price'),
30+
stream('plan'),
31+
stream('coupon'),
32+
stream('credit_note'),
3333
]
3434
const groups = groupStreams(streams)
3535
const billing = groups.find((g) => g.name === 'Billing')
@@ -38,17 +38,17 @@ describe('groupStreams', () => {
3838
})
3939

4040
it('sorts groups alphabetically', () => {
41-
const streams = [stream('products'), stream('customers'), stream('charges')]
41+
const streams = [stream('product'), stream('customer'), stream('charge')]
4242
const groups = groupStreams(streams)
4343
const names = groups.map((g) => g.name)
4444
expect(names).toEqual([...names].sort())
4545
})
4646

4747
it('sorts streams within a group alphabetically', () => {
48-
const streams = [stream('refunds'), stream('charges'), stream('disputes')]
48+
const streams = [stream('refund'), stream('charge'), stream('dispute')]
4949
const groups = groupStreams(streams)
5050
const payments = groups.find((g) => g.name === 'Payments')!
51-
expect(payments.streams.map((s) => s.name)).toEqual(['charges', 'disputes', 'refunds'])
51+
expect(payments.streams.map((s) => s.name)).toEqual(['charge', 'dispute', 'refund'])
5252
})
5353

5454
it('handles dotted names (v2 resources)', () => {
@@ -64,17 +64,14 @@ describe('groupStreams', () => {
6464
})
6565

6666
describe('filterStreams', () => {
67-
const streams = [stream('customers'), stream('charges'), stream('checkout_sessions')]
67+
const streams = [stream('customer'), stream('charge'), stream('checkout_session')]
6868

6969
it('filters by partial name match', () => {
70-
expect(filterStreams(streams, 'ch').map((s) => s.name)).toEqual([
71-
'charges',
72-
'checkout_sessions',
73-
])
70+
expect(filterStreams(streams, 'ch').map((s) => s.name)).toEqual(['charge', 'checkout_session'])
7471
})
7572

7673
it('is case-insensitive', () => {
77-
expect(filterStreams(streams, 'CUSTOMER').map((s) => s.name)).toEqual(['customers'])
74+
expect(filterStreams(streams, 'CUSTOMER').map((s) => s.name)).toEqual(['customer'])
7875
})
7976

8077
it('returns all streams for empty query', () => {

apps/dashboard/src/lib/stream-groups.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface StreamGroup {
1616
* Group streams by inferring categories from their names.
1717
*
1818
* Uses prefix heuristics — not a hardcoded mapping. Streams sharing a
19-
* common prefix word (e.g. "payment_intents", "payment_methods" → "Payment")
19+
* common prefix word (e.g. "payment_intent", "payment_method" → "Payment")
2020
* are grouped together. Single-word names become their own group.
2121
*
2222
* The algorithm:
@@ -56,51 +56,35 @@ export function inferGroupName(streamName: string): string {
5656
// Handle snake_case names — use first word as group
5757
const firstWord = streamName.split('_')[0]
5858

59-
// Map known prefixes to Stripe product groups (both singular and plural forms)
59+
// Map known prefixes to Stripe product groups (singular per resource naming spec).
6060
const REFINEMENTS: Record<string, string> = {
6161
subscription: 'Billing',
62-
subscriptions: 'Billing',
6362
invoice: 'Billing',
64-
invoices: 'Billing',
6563
credit: 'Billing',
6664
price: 'Billing',
67-
prices: 'Billing',
6865
plan: 'Billing',
69-
plans: 'Billing',
7066
coupon: 'Billing',
71-
coupons: 'Billing',
7267
payment: 'Payments',
7368
charge: 'Payments',
74-
charges: 'Payments',
7569
refund: 'Payments',
76-
refunds: 'Payments',
7770
dispute: 'Payments',
78-
disputes: 'Payments',
7971
setup: 'Payments',
8072
checkout: 'Checkout',
8173
customer: 'Customers',
82-
customers: 'Customers',
8374
tax: 'Tax',
8475
product: 'Products',
85-
products: 'Products',
8676
transfer: 'Transfers',
87-
transfers: 'Transfers',
8877
payout: 'Payments',
89-
payouts: 'Payments',
9078
balance: 'Transfers',
9179
application: 'Connect',
9280
account: 'Connect',
93-
accounts: 'Connect',
9481
issuing: 'Issuing',
9582
treasury: 'Treasury',
9683
radar: 'Radar',
9784
early: 'Radar',
9885
file: 'Files',
99-
files: 'Files',
10086
event: 'Events',
101-
events: 'Events',
10287
webhook: 'Webhooks',
103-
webhooks: 'Webhooks',
10488
}
10589

10690
return REFINEMENTS[firstWord] ?? capitalize(firstWord)

apps/engine/src/__tests__/sync.test.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,18 @@ describe('sync lifecycle — run, checkpoint, resume', () => {
128128
it('run 1: writes records and persists state', async () => {
129129
const engine = await createEngine(makeResolver())
130130
const pipeline = {
131-
source: { type: 'test', test: { streams: { customers: {} } } },
131+
source: { type: 'test', test: { streams: { customer: {} } } },
132132
destination: {
133133
type: 'postgres',
134134
postgres: { url: connectionString, schema: SCHEMA },
135135
},
136136
}
137137

138138
const input = [
139-
record('customers', 'cus_1', { name: 'Alice' }),
140-
record('customers', 'cus_2', { name: 'Bob' }),
141-
record('customers', 'cus_3', { name: 'Charlie' }),
142-
state('customers', { after: 'cus_3' }),
139+
record('customer', 'cus_1', { name: 'Alice' }),
140+
record('customer', 'cus_2', { name: 'Bob' }),
141+
record('customer', 'cus_3', { name: 'Charlie' }),
142+
state('customer', { after: 'cus_3' }),
143143
]
144144

145145
// Set up destination schema/tables, then run pipeline
@@ -158,13 +158,13 @@ describe('sync lifecycle — run, checkpoint, resume', () => {
158158

159159
// Verify records were written
160160
const { rows: customers } = await pool.query(
161-
`SELECT count(*)::int AS n FROM "${SCHEMA}".customers`
161+
`SELECT count(*)::int AS n FROM "${SCHEMA}".customer`
162162
)
163163
expect(customers[0].n).toBe(3)
164164

165165
// Verify state was persisted
166166
const { rows: stateRows } = await pool.query(
167-
`SELECT data FROM "${SCHEMA}"."${STATE_TABLE}" WHERE stream = 'customers'`
167+
`SELECT data FROM "${SCHEMA}"."${STATE_TABLE}" WHERE stream = 'customer'`
168168
)
169169
expect(stateRows).toHaveLength(1)
170170
expect(stateRows[0].data).toEqual({ after: 'cus_3' })
@@ -179,17 +179,17 @@ describe('sync lifecycle — run, checkpoint, resume', () => {
179179

180180
const engine = await createEngine(makeResolver())
181181
const pipeline = {
182-
source: { type: 'test', test: { streams: { customers: {} } } },
182+
source: { type: 'test', test: { streams: { customer: {} } } },
183183
destination: {
184184
type: 'postgres',
185185
postgres: { url: connectionString, schema: SCHEMA },
186186
},
187187
}
188188

189189
const input = [
190-
record('customers', 'cus_4', { name: 'Diana' }),
191-
record('customers', 'cus_5', { name: 'Eve' }),
192-
state('customers', { after: 'cus_5' }),
190+
record('customer', 'cus_4', { name: 'Diana' }),
191+
record('customer', 'cus_5', { name: 'Eve' }),
192+
state('customer', { after: 'cus_5' }),
193193
]
194194

195195
for await (const msg of engine.pipeline_sync(
@@ -209,13 +209,13 @@ describe('sync lifecycle — run, checkpoint, resume', () => {
209209

210210
// Verify table now has 5 rows total (3 from run 1 + 2 from run 2)
211211
const { rows: customers } = await pool.query(
212-
`SELECT count(*)::int AS n FROM "${SCHEMA}".customers`
212+
`SELECT count(*)::int AS n FROM "${SCHEMA}".customer`
213213
)
214214
expect(customers[0].n).toBe(5)
215215

216216
// Verify state was updated
217217
const { rows: stateRows } = await pool.query(
218-
`SELECT data FROM "${SCHEMA}"."${STATE_TABLE}" WHERE stream = 'customers'`
218+
`SELECT data FROM "${SCHEMA}"."${STATE_TABLE}" WHERE stream = 'customer'`
219219
)
220220
expect(stateRows).toHaveLength(1)
221221
expect(stateRows[0].data).toEqual({ after: 'cus_5' })

0 commit comments

Comments
 (0)