Browse Source

Better handle first time startup + dedicated event

master
Rory Powell 4 years ago
parent
commit
4cfedf7252
  1. 5
      packages/backend-core/src/events/processors/AnalyticsProcessor.ts
  2. 2
      packages/backend-core/src/events/publishers/index.ts
  3. 13
      packages/backend-core/src/events/publishers/installation.ts
  4. 4
      packages/backend-core/src/installation.ts
  5. 2
      packages/backend-core/tests/utilities/mocks/events.js
  6. 2
      packages/server/src/api/controllers/dev.js
  7. 4
      packages/server/src/api/routes/tests/dev.spec.js
  8. 46
      packages/server/src/migrations/functions/backfill/global.ts
  9. 1
      packages/server/src/migrations/index.ts
  10. 9
      packages/types/src/sdk/events/event.ts

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

@ -7,7 +7,10 @@ import PosthogProcessor from "./PosthogProcessor"
/**
* Events that are always captured.
*/
const EVENT_WHITELIST = [Event.VERSION_UPGRADED, Event.VERSION_DOWNGRADED]
const EVENT_WHITELIST = [
Event.INSTALLATION_VERSION_UPGRADED,
Event.INSTALLATION_VERSION_DOWNGRADED,
]
const IDENTITY_WHITELIST = [IdentityType.INSTALLATION, IdentityType.TENANT]
export default class AnalyticsProcessor implements EventProcessor {

2
packages/backend-core/src/events/publishers/index.ts

@ -15,5 +15,5 @@ export * as table from "./table"
export * as serve from "./serve"
export * as user from "./user"
export * as view from "./view"
export * as version from "./version"
export * as installation from "./installation"
export * as backfill from "./backfill"

13
packages/backend-core/src/events/publishers/version.ts → packages/backend-core/src/events/publishers/installation.ts

@ -1,11 +1,11 @@
import { publishEvent } from "../events"
import { Event, VersionCheckedEvent, VersionChangeEvent } from "@budibase/types"
export async function checked(version: string) {
export async function versionChecked(version: string) {
const properties: VersionCheckedEvent = {
currentVersion: version,
}
await publishEvent(Event.VERSION_CHECKED, properties)
await publishEvent(Event.INSTALLATION_VERSION_CHECKED, properties)
}
export async function upgraded(from: string, to: string) {
@ -14,7 +14,7 @@ export async function upgraded(from: string, to: string) {
to,
}
await publishEvent(Event.VERSION_UPGRADED, properties)
await publishEvent(Event.INSTALLATION_VERSION_UPGRADED, properties)
}
export async function downgraded(from: string, to: string) {
@ -22,5 +22,10 @@ export async function downgraded(from: string, to: string) {
from,
to,
}
await publishEvent(Event.VERSION_DOWNGRADED, properties)
await publishEvent(Event.INSTALLATION_VERSION_DOWNGRADED, properties)
}
export async function firstStartup() {
const properties = {}
await publishEvent(Event.INSTALLATION_FIRST_STARTUP, properties)
}

4
packages/backend-core/src/installation.ts

@ -84,9 +84,9 @@ export const checkInstallVersion = async (): Promise<void> => {
},
async () => {
if (isUpgrade) {
await events.version.upgraded(currentVersion, newVersion)
await events.installation.upgraded(currentVersion, newVersion)
} else if (isDowngrade) {
await events.version.downgraded(currentVersion, newVersion)
await events.installation.downgraded(currentVersion, newVersion)
}
}
)

2
packages/backend-core/tests/utilities/mocks/events.js

@ -55,7 +55,7 @@ jest.spyOn(events.org, "logoUpdated")
jest.spyOn(events.org, "platformURLUpdated")
jest.spyOn(events.org, "analyticsOptOut")
jest.spyOn(events.version, "checked")
jest.spyOn(events.installation, "versionChecked")
jest.spyOn(events.query, "created")
jest.spyOn(events.query, "updated")

2
packages/server/src/api/controllers/dev.js

@ -131,5 +131,5 @@ exports.getBudibaseVersion = async ctx => {
ctx.body = {
version,
}
await events.version.checked(version)
await events.installation.versionChecked(version)
}

4
packages/server/src/api/routes/tests/dev.spec.js

@ -33,8 +33,8 @@ describe("/dev", () => {
.expect(200)
expect(res.body.version).toBe(version)
expect(events.version.checked).toBeCalledTimes(1)
expect(events.version.checked).toBeCalledWith(version)
expect(events.installation.versionChecked).toBeCalledTimes(1)
expect(events.installation.versionChecked).toBeCalledWith(version)
})
})
})

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

@ -14,6 +14,7 @@ import {
App,
TenantBackfillSucceededEvent,
Event,
User,
} from "@budibase/types"
import env from "../../../environment"
import { DEFAULT_TIMESTAMP } from "."
@ -94,8 +95,22 @@ export const run = async (db: any) => {
const totals: any = {}
const errors: any = []
let allUsers: User[] = []
try {
const installTimestamp = await getInstallTimestamp(db)
allUsers = await users.getUsers(db)
} catch (e: any) {
handleError(e, errors)
}
if (!allUsers || allUsers.length === 0) {
// first time startup - we don't need to backfill anything
// tenant will be identified when admin user is created
await events.installation.firstStartup()
return
}
try {
const installTimestamp = await getInstallTimestamp(db, allUsers)
if (installTimestamp) {
timestamp = installTimestamp
}
@ -175,20 +190,25 @@ export const isComplete = async (): Promise<boolean> => {
}
export const getInstallTimestamp = async (
globalDb: any
globalDb: any,
allUsers?: User[]
): Promise<number | undefined> => {
const allUsers = await users.getUsers(globalDb)
if (!allUsers) {
allUsers = await users.getUsers(globalDb)
}
// get the oldest 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]
if (allUsers) {
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]
}
}
}

1
packages/server/src/migrations/index.ts

@ -104,7 +104,6 @@ export const migrate = async (options?: MigrationOptions) => {
const migrateWithLock = async (options?: MigrationOptions) => {
// get a new lock client
const redlock = await redis.clients.getMigrationsRedlock()
// lock for 15 minutes
const ttl = 1000 * 60 * 15

9
packages/types/src/sdk/events/event.ts

@ -39,10 +39,11 @@ export enum Event {
ORG_LOGO_UPDATED = "org:info:logo:updated",
ORG_PLATFORM_URL_UPDATED = "org:platformurl:updated",
// VERSIONS
VERSION_CHECKED = "version:checked",
VERSION_UPGRADED = "version:upgraded",
VERSION_DOWNGRADED = "version:downgraded",
// INSTALLATION
INSTALLATION_VERSION_CHECKED = "installation:version:checked",
INSTALLATION_VERSION_UPGRADED = "installation:version:upgraded",
INSTALLATION_VERSION_DOWNGRADED = "installation:version:downgraded",
INSTALLATION_FIRST_STARTUP = "installation:firstStartup",
// ORG / ANALYTICS
ANALYTICS_OPT_OUT = "analytics:opt:out",

Loading…
Cancel
Save