Browse Source

Historical timestamps

master
Rory Powell 4 years ago
parent
commit
163b667f95
  1. 15
      packages/backend-core/src/events/identification.ts
  2. 6
      packages/backend-core/src/events/processors/AnalyticsProcessor.ts
  3. 8
      packages/backend-core/src/events/processors/PosthogProcessor.ts
  4. 8
      packages/backend-core/src/events/publishers/app.ts
  5. 8
      packages/backend-core/src/events/publishers/auth.ts
  6. 9
      packages/backend-core/src/events/publishers/automation.ts
  7. 4
      packages/backend-core/src/events/publishers/datasource.ts
  8. 7
      packages/backend-core/src/events/publishers/email.ts
  9. 4
      packages/backend-core/src/events/publishers/layout.ts
  10. 12
      packages/backend-core/src/events/publishers/org.ts
  11. 8
      packages/backend-core/src/events/publishers/query.ts
  12. 8
      packages/backend-core/src/events/publishers/role.ts
  13. 4
      packages/backend-core/src/events/publishers/rows.ts
  14. 4
      packages/backend-core/src/events/publishers/screen.ts
  15. 4
      packages/backend-core/src/events/publishers/table.ts
  16. 23
      packages/backend-core/src/events/publishers/user.ts
  17. 15
      packages/backend-core/src/events/publishers/view.ts
  18. 28
      packages/server/src/migrations/functions/backfill/app.ts
  19. 14
      packages/server/src/migrations/functions/backfill/app/apps.ts
  20. 16
      packages/server/src/migrations/functions/backfill/app/automations.ts
  21. 12
      packages/server/src/migrations/functions/backfill/app/datasources.ts
  22. 12
      packages/server/src/migrations/functions/backfill/app/layouts.ts
  23. 20
      packages/server/src/migrations/functions/backfill/app/queries.ts
  24. 12
      packages/server/src/migrations/functions/backfill/app/roles.ts
  25. 12
      packages/server/src/migrations/functions/backfill/app/screens.ts
  26. 28
      packages/server/src/migrations/functions/backfill/app/tables.ts
  27. 24
      packages/server/src/migrations/functions/backfill/global.ts
  28. 25
      packages/server/src/migrations/functions/backfill/global/configs.ts
  29. 20
      packages/server/src/migrations/functions/backfill/global/rows.ts
  30. 17
      packages/server/src/migrations/functions/backfill/global/users.ts
  31. 3
      packages/server/tsconfig.build.json
  32. 3
      packages/server/tsconfig.json
  33. 2
      packages/types/src/documents/document.ts
  34. 5
      packages/types/src/documents/global/user.ts
  35. 1
      packages/types/tsconfig.json
  36. 3
      packages/worker/tsconfig.json

15
packages/backend-core/src/events/identification.ts

@ -79,7 +79,10 @@ const getHostingFromEnv = () => {
return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD
} }
export const identifyTenant = async (tenantId: string) => { export const identifyTenant = async (
tenantId: string,
timestamp?: string | number
) => {
const global = await getGlobalIdentifiers(tenantId) const global = await getGlobalIdentifiers(tenantId)
const identity: TenantIdentity = { const identity: TenantIdentity = {
@ -88,10 +91,10 @@ export const identifyTenant = async (tenantId: string) => {
hosting: getHostingFromEnv(), hosting: getHostingFromEnv(),
type: IdentityType.TENANT, type: IdentityType.TENANT,
} }
await identify(identity) await identify(identity, timestamp)
} }
export const identifyUser = async (user: User) => { export const identifyUser = async (user: User, timestamp?: string | number) => {
const id = user._id as string const id = user._id as string
const tenantId = user.tenantId const tenantId = user.tenantId
const hosting = env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD const hosting = env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD
@ -110,7 +113,7 @@ export const identifyUser = async (user: User) => {
providerType, providerType,
} }
await identify(identity) await identify(identity, timestamp)
} }
export const identifyAccount = async (account: Account) => { export const identifyAccount = async (account: Account) => {
@ -141,6 +144,6 @@ export const identifyAccount = async (account: Account) => {
await identify(identity) await identify(identity)
} }
const identify = async (identity: Identity) => { const identify = async (identity: Identity, timestamp?: string | number) => {
await analyticsProcessor.identify(identity) await analyticsProcessor.identify(identity, timestamp)
} }

6
packages/backend-core/src/events/processors/AnalyticsProcessor.ts

@ -17,7 +17,7 @@ export default class AnalyticsProcessor implements EventProcessor {
event: Event, event: Event,
identity: Identity, identity: Identity,
properties: any, properties: any,
timestamp?: string timestamp?: string | number
): Promise<void> { ): Promise<void> {
if (!(await analytics.enabled())) { if (!(await analytics.enabled())) {
return return
@ -27,12 +27,12 @@ export default class AnalyticsProcessor implements EventProcessor {
} }
} }
async identify(identity: Identity) { async identify(identity: Identity, timestamp?: string | number) {
if (!(await analytics.enabled())) { if (!(await analytics.enabled())) {
return return
} }
if (this.posthog) { if (this.posthog) {
this.posthog.identify(identity) this.posthog.identify(identity, timestamp)
} }
} }

8
packages/backend-core/src/events/processors/PosthogProcessor.ts

@ -25,8 +25,12 @@ export default class PosthogProcessor implements EventProcessor {
this.posthog.capture(payload) this.posthog.capture(payload)
} }
async identify(identity: Identity) { async identify(identity: Identity, timestamp?: string | number) {
this.posthog.identify({ distinctId: identity.id, properties: identity }) const payload: any = { distinctId: identity.id, properties: identity }
if (timestamp) {
payload.timestamp = new Date(timestamp)
}
this.posthog.identify(payload)
} }
shutdown() { shutdown() {

8
packages/backend-core/src/events/publishers/app.ts

@ -15,9 +15,9 @@ import {
AppExportedEvent, AppExportedEvent,
} from "@budibase/types" } from "@budibase/types"
export const created = async (app: App) => { export const created = async (app: App, timestamp?: string | number) => {
const properties: AppCreatedEvent = {} const properties: AppCreatedEvent = {}
await publishEvent(Event.APP_CREATED, properties) await publishEvent(Event.APP_CREATED, properties, timestamp)
} }
export async function updated(app: App) { export async function updated(app: App) {
@ -30,9 +30,9 @@ export async function deleted(app: App) {
await publishEvent(Event.APP_DELETED, properties) await publishEvent(Event.APP_DELETED, properties)
} }
export async function published(app: App) { export async function published(app: App, timestamp?: string | number) {
const properties: AppPublishedEvent = {} const properties: AppPublishedEvent = {}
await publishEvent(Event.APP_PUBLISHED, properties) await publishEvent(Event.APP_PUBLISHED, properties, timestamp)
} }
export async function unpublished(app: App) { export async function unpublished(app: App) {

8
packages/backend-core/src/events/publishers/auth.ts

@ -23,11 +23,11 @@ export async function logout() {
await publishEvent(Event.AUTH_LOGOUT, properties) await publishEvent(Event.AUTH_LOGOUT, properties)
} }
export async function SSOCreated(type: SSOType) { export async function SSOCreated(type: SSOType, timestamp?: string | number) {
const properties: SSOCreatedEvent = { const properties: SSOCreatedEvent = {
type, type,
} }
await publishEvent(Event.AUTH_SSO_CREATED, properties) await publishEvent(Event.AUTH_SSO_CREATED, properties, timestamp)
} }
export async function SSOUpdated(type: SSOType) { export async function SSOUpdated(type: SSOType) {
@ -37,11 +37,11 @@ export async function SSOUpdated(type: SSOType) {
await publishEvent(Event.AUTH_SSO_UPDATED, properties) await publishEvent(Event.AUTH_SSO_UPDATED, properties)
} }
export async function SSOActivated(type: SSOType) { export async function SSOActivated(type: SSOType, timestamp?: string | number) {
const properties: SSOActivatedEvent = { const properties: SSOActivatedEvent = {
type, type,
} }
await publishEvent(Event.AUTH_SSO_ACTIVATED, properties) await publishEvent(Event.AUTH_SSO_ACTIVATED, properties, timestamp)
} }
export async function SSODeactivated(type: SSOType) { export async function SSODeactivated(type: SSOType) {

9
packages/backend-core/src/events/publishers/automation.ts

@ -12,9 +12,9 @@ import {
AutomationTriggerUpdatedEvent, AutomationTriggerUpdatedEvent,
} from "@budibase/types" } from "@budibase/types"
export async function created(automation: Automation) { export async function created(automation: Automation, timestamp?: string) {
const properties: AutomationCreatedEvent = {} const properties: AutomationCreatedEvent = {}
await publishEvent(Event.AUTOMATION_CREATED, properties) await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)
} }
export async function deleted(automation: Automation) { export async function deleted(automation: Automation) {
@ -29,10 +29,11 @@ export async function tested(automation: Automation) {
export async function stepCreated( export async function stepCreated(
automation: Automation, automation: Automation,
step: AutomationStep step: AutomationStep,
timestamp?: string
) { ) {
const properties: AutomationStepCreatedEvent = {} const properties: AutomationStepCreatedEvent = {}
await publishEvent(Event.AUTOMATION_STEP_CREATED, properties) await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)
} }
export async function stepDeleted( export async function stepDeleted(

4
packages/backend-core/src/events/publishers/datasource.ts

@ -7,9 +7,9 @@ import {
DatasourceDeletedEvent, DatasourceDeletedEvent,
} from "@budibase/types" } from "@budibase/types"
export async function created(datasource: Datasource) { export async function created(datasource: Datasource, timestamp?: string) {
const properties: DatasourceCreatedEvent = {} const properties: DatasourceCreatedEvent = {}
await publishEvent(Event.DATASOURCE_CREATED, properties) await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)
} }
export async function updated(datasource: Datasource) { export async function updated(datasource: Datasource) {

7
packages/backend-core/src/events/publishers/email.ts

@ -6,9 +6,12 @@ import {
SMTPUpdatedEvent, SMTPUpdatedEvent,
} from "@budibase/types" } from "@budibase/types"
export async function SMTPCreated(config: SMTPConfig) { export async function SMTPCreated(
config: SMTPConfig,
timestamp?: string | number
) {
const properties: SMTPCreatedEvent = {} const properties: SMTPCreatedEvent = {}
await publishEvent(Event.EMAIL_SMTP_CREATED, properties) await publishEvent(Event.EMAIL_SMTP_CREATED, properties, timestamp)
} }
export async function SMTPUpdated(config: SMTPConfig) { export async function SMTPUpdated(config: SMTPConfig) {

4
packages/backend-core/src/events/publishers/layout.ts

@ -6,9 +6,9 @@ import {
LayoutDeletedEvent, LayoutDeletedEvent,
} from "@budibase/types" } from "@budibase/types"
export async function created(layout: Layout) { export async function created(layout: Layout, timestamp?: string) {
const properties: LayoutCreatedEvent = {} const properties: LayoutCreatedEvent = {}
await publishEvent(Event.LAYOUT_CREATED, properties) await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)
} }
export async function deleted(layout: Layout) { export async function deleted(layout: Layout) {

12
packages/backend-core/src/events/publishers/org.ts

@ -1,19 +1,19 @@
import { publishEvent } from "../events" import { publishEvent } from "../events"
import { Event, VersionCheckedEvent } from "@budibase/types" import { Event, VersionCheckedEvent } from "@budibase/types"
export async function nameUpdated() { export async function nameUpdated(timestamp?: string | number) {
const properties = {} const properties = {}
await publishEvent(Event.ORG_NAME_UPDATED, properties) await publishEvent(Event.ORG_NAME_UPDATED, properties, timestamp)
} }
export async function logoUpdated() { export async function logoUpdated(timestamp?: string | number) {
const properties = {} const properties = {}
await publishEvent(Event.ORG_LOGO_UPDATED, properties) await publishEvent(Event.ORG_LOGO_UPDATED, properties, timestamp)
} }
export async function platformURLUpdated() { export async function platformURLUpdated(timestamp?: string | number) {
const properties = {} const properties = {}
await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties) await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)
} }
export async function versionChecked(version: number) { export async function versionChecked(version: number) {

8
packages/backend-core/src/events/publishers/query.ts

@ -12,9 +12,13 @@ import {
/* eslint-disable */ /* eslint-disable */
export const created = async (datasource: Datasource, query: Query) => { export const created = async (
datasource: Datasource,
query: Query,
timestamp?: string
) => {
const properties: QueryCreatedEvent = {} const properties: QueryCreatedEvent = {}
await publishEvent(Event.QUERY_CREATED, properties) await publishEvent(Event.QUERY_CREATED, properties, timestamp)
} }
export const updated = async (datasource: Datasource, query: Query) => { export const updated = async (datasource: Datasource, query: Query) => {

8
packages/backend-core/src/events/publishers/role.ts

@ -12,9 +12,9 @@ import {
/* eslint-disable */ /* eslint-disable */
export async function created(role: Role) { export async function created(role: Role, timestamp?: string) {
const properties: RoleCreatedEvent = {} const properties: RoleCreatedEvent = {}
await publishEvent(Event.ROLE_CREATED, properties) await publishEvent(Event.ROLE_CREATED, properties, timestamp)
} }
export async function updated(role: Role) { export async function updated(role: Role) {
@ -27,9 +27,9 @@ export async function deleted(role: Role) {
await publishEvent(Event.ROLE_DELETED, properties) await publishEvent(Event.ROLE_DELETED, properties)
} }
export async function assigned(user: User, role: string) { export async function assigned(user: User, role: string, timestamp?: number) {
const properties: RoleAssignedEvent = {} const properties: RoleAssignedEvent = {}
await publishEvent(Event.ROLE_ASSIGNED, properties) await publishEvent(Event.ROLE_ASSIGNED, properties, timestamp)
} }
export async function unassigned(user: User, role: string) { export async function unassigned(user: User, role: string) {

4
packages/backend-core/src/events/publishers/rows.ts

@ -9,11 +9,11 @@ import {
/* eslint-disable */ /* eslint-disable */
export const created = async (count: number) => { export const created = async (count: number, timestamp?: string) => {
const properties: RowsCreatedEvent = { const properties: RowsCreatedEvent = {
count, count,
} }
await publishEvent(Event.ROWS_CREATED, properties) await publishEvent(Event.ROWS_CREATED, properties, timestamp)
} }
export const imported = async ( export const imported = async (

4
packages/backend-core/src/events/publishers/screen.ts

@ -6,9 +6,9 @@ import {
ScreenDeletedEvent, ScreenDeletedEvent,
} from "@budibase/types" } from "@budibase/types"
export async function created(screen: Screen) { export async function created(screen: Screen, timestamp?: string) {
const properties: ScreenCreatedEvent = {} const properties: ScreenCreatedEvent = {}
await publishEvent(Event.SCREEN_CREATED, properties) await publishEvent(Event.SCREEN_CREATED, properties, timestamp)
} }
export async function deleted(screen: Screen) { export async function deleted(screen: Screen) {

4
packages/backend-core/src/events/publishers/table.ts

@ -13,9 +13,9 @@ import {
/* eslint-disable */ /* eslint-disable */
export async function created(table: Table) { export async function created(table: Table, timestamp?: string) {
const properties: TableCreatedEvent = {} const properties: TableCreatedEvent = {}
await publishEvent(Event.TABLE_CREATED, properties) await publishEvent(Event.TABLE_CREATED, properties, timestamp)
} }
export async function updated(table: Table) { export async function updated(table: Table) {

23
packages/backend-core/src/events/publishers/user.ts

@ -17,9 +17,9 @@ import {
/* eslint-disable */ /* eslint-disable */
export async function created(user: User) { export async function created(user: User, timestamp?: number) {
const properties: UserCreatedEvent = {} const properties: UserCreatedEvent = {}
await publishEvent(Event.USER_CREATED, properties) await publishEvent(Event.USER_CREATED, properties, timestamp)
} }
export async function updated(user: User) { export async function updated(user: User) {
@ -34,9 +34,13 @@ export async function deleted(user: User) {
// PERMISSIONS // PERMISSIONS
export async function permissionAdminAssigned(user: User) { export async function permissionAdminAssigned(user: User, timestamp?: number) {
const properties: UserPermissionAssignedEvent = {} const properties: UserPermissionAssignedEvent = {}
await publishEvent(Event.USER_PERMISSION_ADMIN_ASSIGNED, properties) await publishEvent(
Event.USER_PERMISSION_ADMIN_ASSIGNED,
properties,
timestamp
)
} }
export async function permissionAdminRemoved(user: User) { export async function permissionAdminRemoved(user: User) {
@ -44,9 +48,16 @@ export async function permissionAdminRemoved(user: User) {
await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties) await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)
} }
export async function permissionBuilderAssigned(user: User) { export async function permissionBuilderAssigned(
user: User,
timestamp?: number
) {
const properties: UserPermissionAssignedEvent = {} const properties: UserPermissionAssignedEvent = {}
await publishEvent(Event.USER_PERMISSION_BUILDER_ASSIGNED, properties) await publishEvent(
Event.USER_PERMISSION_BUILDER_ASSIGNED,
properties,
timestamp
)
} }
export async function permissionBuilderRemoved(user: User) { export async function permissionBuilderRemoved(user: User) {

15
packages/backend-core/src/events/publishers/view.ts

@ -19,9 +19,9 @@ import {
/* eslint-disable */ /* eslint-disable */
export async function created(view: View) { export async function created(view: View, timestamp?: string) {
const properties: ViewCreatedEvent = {} const properties: ViewCreatedEvent = {}
await publishEvent(Event.VIEW_CREATED, properties) await publishEvent(Event.VIEW_CREATED, properties, timestamp)
} }
export async function updated(view: View) { export async function updated(view: View) {
@ -39,9 +39,9 @@ export async function exported(table: Table, format: TableExportFormat) {
await publishEvent(Event.VIEW_EXPORTED, properties) await publishEvent(Event.VIEW_EXPORTED, properties)
} }
export async function filterCreated() { export async function filterCreated(timestamp?: string) {
const properties: ViewFilterCreatedEvent = {} const properties: ViewFilterCreatedEvent = {}
await publishEvent(Event.VIEW_FILTER_CREATED, properties) await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp)
} }
export async function filterUpdated() { export async function filterUpdated() {
@ -54,9 +54,12 @@ export async function filterDeleted() {
await publishEvent(Event.VIEW_FILTER_DELETED, properties) await publishEvent(Event.VIEW_FILTER_DELETED, properties)
} }
export async function calculationCreated(calculation: ViewCalculation) { export async function calculationCreated(
calculation: ViewCalculation,
timestamp?: string
) {
const properties: ViewCalculationCreatedEvent = {} const properties: ViewCalculationCreatedEvent = {}
await publishEvent(Event.VIEW_CALCULATION_CREATED, properties) await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp)
} }
export async function calculationUpdated() { export async function calculationUpdated() {

28
packages/server/src/migrations/functions/backfill/app.ts

@ -1,4 +1,3 @@
import * as apps from "./app/apps"
import * as automations from "./app/automations" import * as automations from "./app/automations"
import * as datasources from "./app/datasources" import * as datasources from "./app/datasources"
import * as layouts from "./app/layouts" import * as layouts from "./app/layouts"
@ -7,6 +6,8 @@ import * as roles from "./app/roles"
import * as tables from "./app/tables" import * as tables from "./app/tables"
import * as screens from "./app/screens" import * as screens from "./app/screens"
import * as global from "./global" import * as global from "./global"
import { App } from "@budibase/types"
import { db as dbUtils, events } from "@budibase/backend-core"
/** /**
* Date: * Date:
@ -24,12 +25,21 @@ export const run = async (appDb: any) => {
return return
} }
await apps.backfill(appDb) const app: App = await appDb.get(dbUtils.DocumentTypes.APP_METADATA)
await automations.backfill(appDb) const timestamp = app.createdAt as string
await datasources.backfill(appDb)
await layouts.backfill(appDb) if (dbUtils.isDevAppID(app.appId)) {
await queries.backfill(appDb) await events.app.created(app, timestamp)
await roles.backfill(appDb) await automations.backfill(appDb, timestamp)
await tables.backfill(appDb) await datasources.backfill(appDb, timestamp)
await screens.backfill(appDb) await layouts.backfill(appDb, timestamp)
await queries.backfill(appDb, timestamp)
await roles.backfill(appDb, timestamp)
await tables.backfill(appDb, timestamp)
await screens.backfill(appDb, timestamp)
}
if (dbUtils.isProdAppID(app.appId)) {
await events.app.published(app, timestamp)
}
} }

14
packages/server/src/migrations/functions/backfill/app/apps.ts

@ -1,14 +0,0 @@
import { events, db } from "@budibase/backend-core"
import { App } from "@budibase/types"
export const backfill = async (appDb: any) => {
const app: App = await appDb.get(db.DocumentTypes.APP_METADATA)
if (db.isDevAppID(app.appId)) {
await events.app.created(app)
}
if (db.isProdAppID(app.appId)) {
await events.app.published(app)
}
}

16
packages/server/src/migrations/functions/backfill/app/automations.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getAutomationParams } from "../../../../db/utils" import { getAutomationParams } from "../../../../db/utils"
import { Automation } from "@budibase/types" import { Automation } from "@budibase/types"
@ -11,16 +11,14 @@ const getAutomations = async (appDb: any): Promise<Automation[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const automations = await getAutomations(appDb)
const automations = await getAutomations(appDb)
for (const automation of automations) { for (const automation of automations) {
await events.automation.created(automation) await events.automation.created(automation, timestamp)
for (const step of automation.definition.steps) { for (const step of automation.definition.steps) {
await events.automation.stepCreated(automation, step) await events.automation.stepCreated(automation, step, timestamp)
}
} }
} }
} }

12
packages/server/src/migrations/functions/backfill/app/datasources.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getDatasourceParams } from "../../../../db/utils" import { getDatasourceParams } from "../../../../db/utils"
import { Datasource } from "@budibase/types" import { Datasource } from "@budibase/types"
@ -11,12 +11,10 @@ const getDatasources = async (appDb: any): Promise<Datasource[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const datasources: Datasource[] = await getDatasources(appDb)
const datasources: Datasource[] = await getDatasources(appDb)
for (const datasource of datasources) { for (const datasource of datasources) {
await events.datasource.created(datasource) await events.datasource.created(datasource, timestamp)
}
} }
} }

12
packages/server/src/migrations/functions/backfill/app/layouts.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getLayoutParams } from "../../../../db/utils" import { getLayoutParams } from "../../../../db/utils"
import { Layout } from "@budibase/types" import { Layout } from "@budibase/types"
@ -11,12 +11,10 @@ const getLayouts = async (appDb: any): Promise<Layout[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const layouts: Layout[] = await getLayouts(appDb)
const layouts: Layout[] = await getLayouts(appDb)
for (const layout of layouts) { for (const layout of layouts) {
await events.layout.created(layout) await events.layout.created(layout, timestamp)
}
} }
} }

20
packages/server/src/migrations/functions/backfill/app/queries.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getQueryParams } from "../../../../db/utils" import { getQueryParams } from "../../../../db/utils"
import { Query, Datasource } from "@budibase/types" import { Query, Datasource } from "@budibase/types"
@ -18,16 +18,14 @@ const getDatasource = async (
return appDb.get(datasourceId) return appDb.get(datasourceId)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const queries: Query[] = await getQueries(appDb)
const queries: Query[] = await getQueries(appDb)
for (const query of queries) { for (const query of queries) {
const datasource: Datasource = await getDatasource( const datasource: Datasource = await getDatasource(
appDb, appDb,
query.datasourceId query.datasourceId
) )
await events.query.created(datasource, query) await events.query.created(datasource, query, timestamp)
}
} }
} }

12
packages/server/src/migrations/functions/backfill/app/roles.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getRoleParams } from "../../../../db/utils" import { getRoleParams } from "../../../../db/utils"
import { Role } from "@budibase/types" import { Role } from "@budibase/types"
@ -11,12 +11,10 @@ const getRoles = async (appDb: any): Promise<Role[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const roles = await getRoles(appDb)
const roles = await getRoles(appDb)
for (const role of roles) { for (const role of roles) {
await events.role.created(role) await events.role.created(role, timestamp)
}
} }
} }

12
packages/server/src/migrations/functions/backfill/app/screens.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getScreenParams } from "../../../../db/utils" import { getScreenParams } from "../../../../db/utils"
import { Screen } from "@budibase/types" import { Screen } from "@budibase/types"
@ -11,12 +11,10 @@ const getScreens = async (appDb: any): Promise<Screen[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const screens = await getScreens(appDb)
const screens = await getScreens(appDb)
for (const screen of screens) { for (const screen of screens) {
await events.screen.created(screen) await events.screen.created(screen, timestamp)
}
} }
} }

28
packages/server/src/migrations/functions/backfill/app/tables.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
import { getTableParams } from "../../../../db/utils" import { getTableParams } from "../../../../db/utils"
import { Table } from "@budibase/types" import { Table } from "@budibase/types"
@ -11,24 +11,22 @@ const getTables = async (appDb: any): Promise<Table[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (appDb: any) => { export const backfill = async (appDb: any, timestamp: string) => {
if (db.isDevAppID(appDb.name)) { const tables = await getTables(appDb)
const tables = await getTables(appDb)
for (const table of tables) { for (const table of tables) {
await events.table.created(table) await events.table.created(table, timestamp)
if (table.views) { if (table.views) {
for (const view of Object.values(table.views)) { for (const view of Object.values(table.views)) {
await events.view.created(view) await events.view.created(view, timestamp)
if (view.calculation) { if (view.calculation) {
await events.view.calculationCreated(view.calculation) await events.view.calculationCreated(view.calculation, timestamp)
} }
if (view.filters?.length) { if (view.filters?.length) {
await events.view.filterCreated() await events.view.filterCreated(timestamp)
}
} }
} }
} }

24
packages/server/src/migrations/functions/backfill/global.ts

@ -13,11 +13,14 @@ import { tenancy, events, migrations } from "@budibase/backend-core"
export const run = async (db: any) => { export const run = async (db: any) => {
const tenantId = tenancy.getTenantId() const tenantId = tenancy.getTenantId()
await events.identification.identifyTenant(tenantId) const installTimestamp = (await getInstallTimestamp(db)) as number
await events.identification.identifyTenant(tenantId, installTimestamp)
await configs.backfill(db, installTimestamp)
// users and rows provide their own timestamp
await users.backfill(db) await users.backfill(db)
await rows.backfill() await rows.backfill()
await configs.backfill(db)
} }
export const isComplete = async (): Promise<boolean> => { export const isComplete = async (): Promise<boolean> => {
@ -25,3 +28,20 @@ export const isComplete = async (): Promise<boolean> => {
const migrationsDoc = await migrations.getMigrationsDoc(globalDb) const migrationsDoc = await migrations.getMigrationsDoc(globalDb)
return !!migrationsDoc.event_global_backfill return !!migrationsDoc.event_global_backfill
} }
const getInstallTimestamp = async (db: any): Promise<number | undefined> => {
const allUsers = await users.getUsers(db)
// get the olders user timestamp
const timestamps = allUsers
.map(user => user.createdAt)
.filter(timestamp => !!timestamp)
.sort(
(a, b) =>
new Date(a as number).getTime() - new Date(b as number).getTime()
)
if (timestamps.length) {
return timestamps[0]
}
}

25
packages/server/src/migrations/functions/backfill/global/configs.ts

@ -1,4 +1,4 @@
import { events, db } from "@budibase/backend-core" import { events, db as dbUtils } from "@budibase/backend-core"
import { import {
Config, Config,
isSMTPConfig, isSMTPConfig,
@ -10,7 +10,7 @@ import env from "./../../../../environment"
const getConfigs = async (globalDb: any): Promise<Config[]> => { const getConfigs = async (globalDb: any): Promise<Config[]> => {
const response = await globalDb.allDocs( const response = await globalDb.allDocs(
db.getConfigParams( dbUtils.getConfigParams(
{}, {},
{ {
include_docs: true, include_docs: true,
@ -20,34 +20,37 @@ const getConfigs = async (globalDb: any): Promise<Config[]> => {
return response.rows.map((row: any) => row.doc) return response.rows.map((row: any) => row.doc)
} }
export const backfill = async (globalDb: any) => { export const backfill = async (
globalDb: any,
timestamp: string | number | undefined
) => {
const configs = await getConfigs(globalDb) const configs = await getConfigs(globalDb)
for (const config of configs) { for (const config of configs) {
if (isSMTPConfig(config)) { if (isSMTPConfig(config)) {
await events.email.SMTPCreated(config) await events.email.SMTPCreated(config, timestamp)
} }
if (isGoogleConfig(config)) { if (isGoogleConfig(config)) {
await events.auth.SSOCreated("google") await events.auth.SSOCreated("google", timestamp)
if (config.config.activated) { if (config.config.activated) {
await events.auth.SSOActivated("google") await events.auth.SSOActivated("google", timestamp)
} }
} }
if (isOIDCConfig(config)) { if (isOIDCConfig(config)) {
await events.auth.SSOCreated("oidc") await events.auth.SSOCreated("oidc", timestamp)
if (config.config.configs[0].activated) { if (config.config.configs[0].activated) {
await events.auth.SSOActivated("oidc") await events.auth.SSOActivated("oidc", timestamp)
} }
} }
if (isSettingsConfig(config)) { if (isSettingsConfig(config)) {
const company = config.config.company const company = config.config.company
if (company && company !== "Budibase") { if (company && company !== "Budibase") {
await events.org.nameUpdated() await events.org.nameUpdated(timestamp)
} }
const logoUrl = config.config.logoUrl const logoUrl = config.config.logoUrl
if (logoUrl) { if (logoUrl) {
await events.org.logoUpdated() await events.org.logoUpdated(timestamp)
} }
const platformUrl = config.config.platformUrl const platformUrl = config.config.platformUrl
@ -56,7 +59,7 @@ export const backfill = async (globalDb: any) => {
platformUrl !== "http://localhost:10000" && platformUrl !== "http://localhost:10000" &&
env.SELF_HOSTED env.SELF_HOSTED
) { ) {
await events.org.platformURLUpdated() await events.org.platformURLUpdated(timestamp)
} }
} }
} }

20
packages/server/src/migrations/functions/backfill/global/rows.ts

@ -1,16 +1,28 @@
import { events, db } from "@budibase/backend-core" import { events, db as dbUtils } from "@budibase/backend-core"
import { Row } from "@budibase/types" import { Row, App } from "@budibase/types"
import { getUniqueRows } from "../../../../utilities/usageQuota/rows" import { getUniqueRows } from "../../../../utilities/usageQuota/rows"
// Rows is a special circumstance where we get rows across all apps // Rows is a special circumstance where we get rows across all apps
// therefore migration is performed at the global level // therefore migration is performed at the global level
const getOldestCreatedAt = (allApps: App[]): string | undefined => {
const timestamps = allApps
.filter(app => !!app.createdAt)
.map(app => app.createdAt as string)
.sort((a, b) => new Date(a).getTime() - new Date(b).getTime())
if (timestamps.length) {
return timestamps[0]
}
}
export const backfill = async () => { export const backfill = async () => {
const allApps = await db.getAllApps({ all: true }) const allApps: App[] = await dbUtils.getAllApps({ dev: true })
const timestamp = getOldestCreatedAt(allApps)
const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : [] const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : []
const rows: Row[] = await getUniqueRows(appIds) const rows: Row[] = await getUniqueRows(appIds)
const rowCount = rows ? rows.length : 0 const rowCount = rows ? rows.length : 0
if (rowCount) { if (rowCount) {
await events.rows.created(rowCount) await events.rows.created(rowCount, timestamp)
} }
} }

17
packages/server/src/migrations/functions/backfill/global/users.ts

@ -1,12 +1,12 @@
import { events, db } from "@budibase/backend-core" import { events, db as dbUtils } from "@budibase/backend-core"
import { User } from "@budibase/types" import { User } from "@budibase/types"
// manually define user doc params - normally server doesn't read users from the db // manually define user doc params - normally server doesn't read users from the db
const getUserParams = (props: any) => { const getUserParams = (props: any) => {
return db.getDocParams(db.DocumentTypes.USER, null, props) return dbUtils.getDocParams(dbUtils.DocumentTypes.USER, null, props)
} }
const getUsers = async (globalDb: any): Promise<User[]> => { export const getUsers = async (globalDb: any): Promise<User[]> => {
const response = await globalDb.allDocs( const response = await globalDb.allDocs(
getUserParams({ getUserParams({
include_docs: true, include_docs: true,
@ -19,20 +19,21 @@ export const backfill = async (globalDb: any) => {
const users = await getUsers(globalDb) const users = await getUsers(globalDb)
for (const user of users) { for (const user of users) {
await events.identification.identifyUser(user) const timestamp = user.createdAt as number
await events.user.created(user) await events.identification.identifyUser(user, timestamp)
await events.user.created(user, timestamp)
if (user.admin?.global) { if (user.admin?.global) {
await events.user.permissionAdminAssigned(user) await events.user.permissionAdminAssigned(user, timestamp)
} }
if (user.builder?.global) { if (user.builder?.global) {
await events.user.permissionBuilderAssigned(user) await events.user.permissionBuilderAssigned(user, timestamp)
} }
if (user.roles) { if (user.roles) {
for (const [appId, role] of Object.entries(user.roles)) { for (const [appId, role] of Object.entries(user.roles)) {
await events.role.assigned(user, role) await events.role.assigned(user, role, timestamp)
} }
} }
} }

3
packages/server/tsconfig.build.json

@ -2,7 +2,8 @@
// Used for building with tsc // Used for building with tsc
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"references": [ "references": [
{ "path": "../backend-core/tsconfig.build.json" } { "path": "../backend-core/tsconfig.build.json" },
{ "path": "../types" }
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules",

3
packages/server/tsconfig.json

@ -16,9 +16,6 @@
"./src/**/*", "./src/**/*",
"./src/module.d.ts" "./src/module.d.ts"
], ],
"references": [
{ "path": "../backend-core/tsconfig.build.json" }
],
"exclude": [ "exclude": [
"node_modules", "node_modules",
"**/*.json", "**/*.json",

2
packages/types/src/documents/document.ts

@ -1,6 +1,6 @@
export interface Document { export interface Document {
_id?: string _id?: string
_rev?: string _rev?: string
createdAt?: string createdAt?: string | number
updatedAt?: string updatedAt?: string
} }

5
packages/types/src/documents/global/user.ts

@ -1,6 +1,8 @@
import { Document } from "../document" import { Document } from "../document"
export interface User extends Document { export interface User extends Document {
tenantId: string
email: string
roles: UserRoles roles: UserRoles
builder?: { builder?: {
global: boolean global: boolean
@ -9,10 +11,9 @@ export interface User extends Document {
global: boolean global: boolean
} }
providerType?: string providerType?: string
tenantId: string
email: string
password?: string password?: string
status?: string status?: string
createdAt?: number // override the default createdAt behaviour - users sdk historically set this to Date.now()
} }
export interface UserRoles { export interface UserRoles {

1
packages/types/tsconfig.json

@ -10,6 +10,7 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"incremental": true, "incremental": true,
"types": [ "node"], "types": [ "node"],
"composite": true
}, },
"include": [ "include": [
"**/*.ts", "**/*.ts",

3
packages/worker/tsconfig.json

@ -13,7 +13,8 @@
"types": [ "node", "jest"], "types": [ "node", "jest"],
}, },
"references": [ "references": [
{ "path": "../backend-core/tsconfig.build.json" } { "path": "../backend-core/tsconfig.build.json" },
{ "path": "../types" }
], ],
"include": [ "include": [
"./src/**/*" "./src/**/*"

Loading…
Cancel
Save