-
Notifications
You must be signed in to change notification settings - Fork 12
feat: data checklist #755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: data checklist #755
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@flatfile/plugin-space-configure': minor | ||
| --- | ||
|
|
||
| This release adds a data checklist utility that can be used to create a Data Checklist Document |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,12 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import type { FlatfileListener } from '@flatfile/listener' | ||||||||||||||||||||||||||||||||||||||||||
| import type { FlatfileEvent, FlatfileListener } from '@flatfile/listener' | ||||||||||||||||||||||||||||||||||||||||||
| import { exportDelimitedZip } from '@flatfile/plugin-export-delimited-zip' | ||||||||||||||||||||||||||||||||||||||||||
| import { type TickFunction } from '@flatfile/plugin-job-handler' | ||||||||||||||||||||||||||||||||||||||||||
| import { JSONExtractor } from '@flatfile/plugin-json-extractor' | ||||||||||||||||||||||||||||||||||||||||||
| import { bulkRecordHook } from '@flatfile/plugin-record-hook' | ||||||||||||||||||||||||||||||||||||||||||
| import { configureSpace } from '@flatfile/plugin-space-configure' | ||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||
| configureSpace, | ||||||||||||||||||||||||||||||||||||||||||
| createDataChecklist, | ||||||||||||||||||||||||||||||||||||||||||
| } from '@flatfile/plugin-space-configure' | ||||||||||||||||||||||||||||||||||||||||||
| import { storedConstraint } from '@flatfile/plugin-stored-constraints' | ||||||||||||||||||||||||||||||||||||||||||
| import { ExcelExtractor } from '@flatfile/plugin-xlsx-extractor' | ||||||||||||||||||||||||||||||||||||||||||
| import { contacts } from './sheets/contacts' | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -32,20 +38,130 @@ export default async function (listener: FlatfileListener) { | |||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| listener.use( | ||||||||||||||||||||||||||||||||||||||||||
| configureSpace({ | ||||||||||||||||||||||||||||||||||||||||||
| workbooks: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| name: 'Sandbox', | ||||||||||||||||||||||||||||||||||||||||||
| sheets: [contacts], | ||||||||||||||||||||||||||||||||||||||||||
| actions: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| operation: 'export-delimited-zip', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Export to Delimited ZIP', | ||||||||||||||||||||||||||||||||||||||||||
| mode: 'foreground', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| configureSpace( | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| workbooks: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| name: 'Sandbox', | ||||||||||||||||||||||||||||||||||||||||||
| sheets: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| name: 'Sales', | ||||||||||||||||||||||||||||||||||||||||||
| slug: 'sales', | ||||||||||||||||||||||||||||||||||||||||||
| fields: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'date', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Date', | ||||||||||||||||||||||||||||||||||||||||||
| description: 'The date of the sale', | ||||||||||||||||||||||||||||||||||||||||||
| constraints: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| type: 'required', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| type: 'unique', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'product', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Product', | ||||||||||||||||||||||||||||||||||||||||||
| description: 'The product sold', | ||||||||||||||||||||||||||||||||||||||||||
| constraints: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| type: 'required', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'category', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Category', | ||||||||||||||||||||||||||||||||||||||||||
| description: 'The category of the product', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'region', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Region', | ||||||||||||||||||||||||||||||||||||||||||
| description: 'The region of the sale', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'salesAmount', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Sales Amount', | ||||||||||||||||||||||||||||||||||||||||||
| description: 'The amount of the sale', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+89
to
+93
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add validation for sales amount. The 'salesAmount' field should validate for non-negative values. Add a minimum value constraint: {
key: 'salesAmount',
type: 'number',
label: 'Sales Amount',
description: 'The amount of the sale',
+ constraints: [
+ {
+ type: 'required'
+ },
+ {
+ type: 'min',
+ value: 0,
+ message: 'Sales amount cannot be negative'
+ }
+ ]
},📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| actions: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| operation: 'generateExampleRecords', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Generate Example Records', | ||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||
| 'This custom action code generates example records using Anthropic.', | ||||||||||||||||||||||||||||||||||||||||||
| primary: false, | ||||||||||||||||||||||||||||||||||||||||||
| mode: 'foreground', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| name: 'Sales 2', | ||||||||||||||||||||||||||||||||||||||||||
| slug: 'sales-2', | ||||||||||||||||||||||||||||||||||||||||||
| fields: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'date', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Date', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'product', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Product', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'category', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Category', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'region', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Region', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| key: 'salesAmount', | ||||||||||||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Sales Amount', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| actions: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| operation: 'export-external-api', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Export to External API', | ||||||||||||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||||||||||||
| 'This custom action code exports the records in the Sales sheet to an external API.', | ||||||||||||||||||||||||||||||||||||||||||
| primary: false, | ||||||||||||||||||||||||||||||||||||||||||
| mode: 'foreground', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| actions: [ | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| operation: 'export-delimited-zip', | ||||||||||||||||||||||||||||||||||||||||||
| label: 'Export to Delimited ZIP', | ||||||||||||||||||||||||||||||||||||||||||
| mode: 'foreground', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| async ( | ||||||||||||||||||||||||||||||||||||||||||
| event: FlatfileEvent, | ||||||||||||||||||||||||||||||||||||||||||
| _workbookIds: string[], | ||||||||||||||||||||||||||||||||||||||||||
| _tick: TickFunction | ||||||||||||||||||||||||||||||||||||||||||
| ) => { | ||||||||||||||||||||||||||||||||||||||||||
| await createDataChecklist(event.context.spaceId) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export * from './space.configure' | ||
| export * from './utils/data.checklist' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import { Flatfile, FlatfileClient } from '@flatfile/api' | ||
|
|
||
| const api = new FlatfileClient() | ||
|
|
||
| export const createDataChecklist = async (spaceId: Flatfile.SpaceId) => { | ||
| const { data: workbooks } = await api.workbooks.list({ spaceId }) | ||
|
|
||
| let body = `<div class="my-doc">\n` | ||
|
|
||
| for (const workbook of workbooks) { | ||
| const { data: sheets } = await api.sheets.list({ workbookId: workbook.id }) | ||
| body += ` <h2>${workbook.name}</h2>` | ||
|
|
||
| for (const sheet of sheets) { | ||
| const fields = sheet.config.fields | ||
| const fieldTable = fields | ||
| .map((field) => { | ||
| const constraints = field.constraints | ||
| ?.map( | ||
| (constraint) => | ||
| `<span style="color: #d97a71; background-color: #fff0ef; padding: 2px 6px; border-radius: 5px; margin-left: 8px;">${constraint.type}</span>` | ||
| ) | ||
| .join('') | ||
| return ` | ||
| <tr> | ||
| <td style="padding:8px; border-bottom:1px solid #f3f2f2;">${field.label}${constraints ?? ''}</td> | ||
| <td style="padding:8px; border-bottom:1px solid #f3f2f2;"><span style="color: #2e424b; background-color: #f0f0f0; padding: 2px 6px; border-radius: 5px;">${field.type}</span></td> | ||
| <td style="padding:8px; border-bottom:1px solid #f3f2f2;">${field.description || ''}</td> | ||
| </tr>` | ||
| }) | ||
| .join('') | ||
|
|
||
| body += ` | ||
| <h3>${sheet.name}</h3> | ||
| <table style="width:100%; border-collapse: collapse;"> | ||
| <thead> | ||
| <tr> | ||
| <th style="text-align:left; padding:8px; border-bottom:1px solid #ddd; width: 25%;">Field Name</th> | ||
| <th style="text-align:left; padding:8px; border-bottom:1px solid #ddd; width: 10%;">Data Type</th> | ||
| <th style="text-align:left; padding:8px; border-bottom:1px solid #ddd; width: 65%;">Description</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody>${fieldTable} | ||
| </tbody> | ||
| </table>` | ||
| } | ||
| } | ||
|
|
||
| body += `\n</div>` | ||
|
|
||
| await api.documents.create(spaceId, { | ||
| title: `Data Checklist`, | ||
| body, | ||
| }) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add date format validation.
The 'date' field is defined as a string type without format validation, which could lead to inconsistent date formats.
Add a format constraint:
{ key: 'date', type: 'string', label: 'Date', description: 'The date of the sale', constraints: [ { type: 'required', }, { type: 'unique', }, + { + type: 'regex', + pattern: '^\\d{4}-\\d{2}-\\d{2}$', + message: 'Date must be in YYYY-MM-DD format' + } ], },📝 Committable suggestion