Skip to content

Commit

Permalink
Consolidate status and activity fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebroberts committed Jul 8, 2024
1 parent 10a13bf commit 1db910b
Show file tree
Hide file tree
Showing 20 changed files with 212 additions and 154 deletions.
16 changes: 5 additions & 11 deletions src/app/lambdaFunctions/authenticatedWeb/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,16 @@ import { startSetupRoute } from '../../domain/github/setup/startGithubSetup'
import { isFailure } from '../../util/structuredResult'
import { a, p } from '../../web/hiccough/hiccoughElements'
import { repoHeadingRoute } from '../../web/fragments/repoHeading'
import { repoActionsStatusRoute } from '../../web/fragments/repoActionsStatus'
import { repoRecentActivityRoute } from '../../web/fragments/repoRecentActivity'
import { homeActionsStatusRoute } from '../../web/fragments/homeActionsStatus'
import { homeRecentActivityRoute } from '../../web/fragments/homeRecentActivity'
import { actionsStatusRoute } from '../../web/fragments/actionsStatus'
import { gitHubActivityRoute } from '../../web/fragments/gitHubActivity'
import { workflowHeadingRoute } from '../../web/fragments/workflowHeading'
import { workflowActivityRoute } from '../../web/fragments/workflowActivity'

const router = createRouter([
showHelloRoute,
homeActionsStatusRoute,
homeRecentActivityRoute,
repoHeadingRoute,
repoActionsStatusRoute,
repoRecentActivityRoute,
workflowHeadingRoute,
workflowActivityRoute
actionsStatusRoute,
gitHubActivityRoute,
workflowHeadingRoute
])

let appState: AppState
Expand Down
50 changes: 50 additions & 0 deletions src/app/web/fragments/actionsStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { AppState } from '../../environment/AppState'
import { Route } from '../../internalHttpRouter/internalHttpRoute'
import { CicadaAuthorizedAPIEvent } from '../../inboundInterfaces/lambdaTypes'
import { isFailure } from '../../util/structuredResult'
import { getRepository } from '../../domain/github/githubRepository'
import {
latestWorkflowRunEventsPerWorkflowForOwners,
latestWorkflowRunEventsPerWorkflowForRepo
} from '../../domain/github/githubLatestWorkflowRunEvents'
import { invalidRequestResponse, notFoundHTMLResponse } from '../htmlResponses'
import { createWorkflowRunEventTableResponse } from './views/activityAndStatusView'
import { getAllAccountIdsForUser } from '../../domain/github/githubMembership'
import { getOptionalRepoCoordinates } from './requestParsing/getOptionalRepoCoordinates'

export const actionsStatusRoute: Route<CicadaAuthorizedAPIEvent> = {
path: '/app/fragment/actionsStatus',
target: actionsStatus
}

export async function actionsStatus(appState: AppState, event: CicadaAuthorizedAPIEvent) {
const coordinatesResult = getOptionalRepoCoordinates(event)

if (isFailure(coordinatesResult)) return coordinatesResult.failureResult
const { ownerId, repoId } = coordinatesResult.result

if (ownerId && repoId) return await actionsStatusForRepo(appState, ownerId, repoId)
if (!ownerId && !repoId) return actionsStatusForHome(appState, event.userId)
return invalidRequestResponse
}

async function actionsStatusForRepo(appState: AppState, ownerId: number, repoId: number) {
// TODO eventually - make sure user has permission for this
// TODO eventually - move repo check into domain logic
if (!(await getRepository(appState, ownerId, repoId))) return notFoundHTMLResponse

return createWorkflowRunEventTableResponse(
'repoStatus',
appState.clock,
await latestWorkflowRunEventsPerWorkflowForRepo(appState, ownerId, repoId)
)
}

async function actionsStatusForHome(appState: AppState, userId: number) {
const accountIds = await getAllAccountIdsForUser(appState, userId)
return createWorkflowRunEventTableResponse(
'homeStatus',
appState.clock,
await latestWorkflowRunEventsPerWorkflowForOwners(appState, accountIds)
)
}
74 changes: 74 additions & 0 deletions src/app/web/fragments/gitHubActivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { AppState } from '../../environment/AppState'
import { Route } from '../../internalHttpRouter/internalHttpRoute'
import { CicadaAuthorizedAPIEvent } from '../../inboundInterfaces/lambdaTypes'
import { isFailure } from '../../util/structuredResult'
import { getRepository } from '../../domain/github/githubRepository'
import { getRecentActivityForRepo } from '../../domain/github/githubActivity'
import { invalidRequestResponse, notFoundHTMLResponse } from '../htmlResponses'
import {
createGithubActivityResponse,
createGithubPushTableResponse,
createWorkflowRunEventTableResponse
} from './views/activityAndStatusView'
import { getOptionalWorkflowCoordinates } from './requestParsing/getOptionalWorkflowCoordinates'
import { getRunEventsForWorkflow } from '../../domain/github/githubWorkflowRunEvent'
import { recentActiveBranchesForOwners } from '../../domain/github/githubLatestPushesPerRef'
import { getAllAccountIdsForUser } from '../../domain/github/githubMembership'
import { logger } from '../../util/logging'

export const gitHubActivityRoute: Route<CicadaAuthorizedAPIEvent> = {
path: '/app/fragment/gitHubActivity',
target: gitHubActivity
}

export async function gitHubActivity(appState: AppState, event: CicadaAuthorizedAPIEvent) {
const coordinatesResult = getOptionalWorkflowCoordinates(event)

if (isFailure(coordinatesResult)) return coordinatesResult.failureResult
const { ownerId, repoId, workflowId } = coordinatesResult.result

if (ownerId && repoId) {
return workflowId
? await githubActivityForWorkflow(appState, ownerId, repoId, workflowId)
: await githubActivityForRepo(appState, ownerId, repoId)
}
if (!ownerId && !repoId) return await githubActivityForHome(appState, event.userId)
return invalidRequestResponse
}

async function githubActivityForWorkflow(
appState: AppState,
ownerId: number,
repoId: number,
workflowId: number
) {
logger.debug('githubActivityForWorkflow', { ownerId, repoId, workflowId })
// TODO eventually - make sure user has permission for this
return createWorkflowRunEventTableResponse(
'workflowActivity',
appState.clock,
await getRunEventsForWorkflow(appState, ownerId, repoId, workflowId)
)
}

async function githubActivityForRepo(appState: AppState, ownerId: number, repoId: number) {
logger.debug('githubActivityForRepo')
if (!(await getRepository(appState, ownerId, repoId))) return notFoundHTMLResponse

// TODO eventually - make sure user has permission for this
// TODO eventually - move repo check into domain logic
return createGithubActivityResponse(
'repoActivity',
appState.clock,
await getRecentActivityForRepo(appState, ownerId, repoId)
)
}

async function githubActivityForHome(appState: AppState, userId: number) {
logger.debug('githubActivityForHome')
return createGithubPushTableResponse(
'homeActivity',
appState.clock,
await recentActiveBranchesForOwners(appState, await getAllAccountIdsForUser(appState, userId))
)
}
21 changes: 0 additions & 21 deletions src/app/web/fragments/homeActionsStatus.ts

This file was deleted.

21 changes: 0 additions & 21 deletions src/app/web/fragments/homeRecentActivity.ts

This file was deleted.

31 changes: 0 additions & 31 deletions src/app/web/fragments/repoActionsStatus.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/web/fragments/repoHeading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isFailure } from '../../util/structuredResult'
import { getRepository } from '../../domain/github/githubRepository'
import { createRepoHeadingResponse } from './views/repoHeadingView'
import { notFoundHTMLResponse } from '../htmlResponses'
import { getRepoCoordinates } from './requestProcessing/getRepoCoordinates'
import { getRepoCoordinates } from './requestParsing/getRepoCoordinates'

export const repoHeadingRoute: Route<CicadaAuthorizedAPIEvent> = {
path: '/app/fragment/repo/heading',
Expand Down
31 changes: 0 additions & 31 deletions src/app/web/fragments/repoRecentActivity.ts

This file was deleted.

33 changes: 33 additions & 0 deletions src/app/web/fragments/requestParsing/getOptionalRepoCoordinates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CicadaAuthorizedAPIEvent } from '../../../inboundInterfaces/lambdaTypes'
import { failedWithResult, isFailure, Result, successWith } from '../../../util/structuredResult'
import { APIGatewayProxyResult } from 'aws-lambda/trigger/api-gateway-proxy'
import { logger } from '../../../util/logging'
import { invalidRequestResponse } from '../../htmlResponses'
import { validatingQueryStringParser } from '../../../schema/urlPathParser'
import { JTDSchemaType } from 'ajv/dist/jtd'
import { RepoCoordinatesQueryStringParameters, repoCoordinatesSchema } from './getRepoCoordinates'

export function getOptionalRepoCoordinates(
event: CicadaAuthorizedAPIEvent
): Result<{ ownerId?: number; repoId?: number }, APIGatewayProxyResult> {
const parseResult = parser(event.queryStringParameters ?? {})
if (isFailure(parseResult)) {
logger.warn('Invalid request in getOptionalRepoCoordinates', { reason: parseResult.reason })
return failedWithResult('Failed to parse', invalidRequestResponse)
}

// TODO - can we just define the schema with ints?
const { ownerId, repoId } = parseResult.result
return successWith({
...(ownerId ? { ownerId: parseInt(ownerId) } : {}),
...(repoId ? { repoId: parseInt(repoId) } : {})
})
}

export type OptionalRepoCoordinatesQueryStringParameters = Partial<RepoCoordinatesQueryStringParameters>

export const optionalRepoCoordinatesSchema: JTDSchemaType<OptionalRepoCoordinatesQueryStringParameters> = {
optionalProperties: repoCoordinatesSchema.properties
}

const parser = validatingQueryStringParser(optionalRepoCoordinatesSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { CicadaAuthorizedAPIEvent } from '../../../inboundInterfaces/lambdaTypes'
import { JTDSchemaType } from 'ajv/dist/jtd'
import { validatingQueryStringParser } from '../../../schema/urlPathParser'
import { failedWithResult, isFailure, Result, successWith } from '../../../util/structuredResult'
import { logger } from '../../../util/logging'
import { APIGatewayProxyResult } from 'aws-lambda/trigger/api-gateway-proxy'
import { invalidRequestResponse } from '../../htmlResponses'
import { WorkflowCoordinatesQueryStringParameters, workflowCoordinatesSchema } from './getWorkflowCoordinates'

export function getOptionalWorkflowCoordinates(
event: CicadaAuthorizedAPIEvent
): Result<{ ownerId?: number; repoId?: number; workflowId?: number }, APIGatewayProxyResult> {
const parseResult = parser(event.queryStringParameters ?? {})
if (isFailure(parseResult)) {
logger.warn('Invalid request in getOptionalWorkflowCoordinates', { reason: parseResult.reason })
return failedWithResult('Failed to parse', invalidRequestResponse)
}

// TODO - can we just define the schema with ints?
const { ownerId, repoId, workflowId } = parseResult.result
return successWith({
...(ownerId ? { ownerId: parseInt(ownerId) } : {}),
...(repoId ? { repoId: parseInt(repoId) } : {}),
...(workflowId ? { workflowId: parseInt(workflowId) } : {})
})
}

export type OptionalWorkflowCoordinatesQueryStringParameters =
Partial<WorkflowCoordinatesQueryStringParameters>

export const optionalWorkflowCoordinatesSchema: JTDSchemaType<OptionalWorkflowCoordinatesQueryStringParameters> =
{
optionalProperties: workflowCoordinatesSchema.properties
}

const parser = validatingQueryStringParser(optionalWorkflowCoordinatesSchema)
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { invalidRequestResponse } from '../../htmlResponses'
export function getRepoCoordinates(
event: CicadaAuthorizedAPIEvent
): Result<{ ownerId: number; repoId: number }, APIGatewayProxyResult> {
const parseResult = qsParser(event.queryStringParameters)
const parseResult = parser(event.queryStringParameters)
if (isFailure(parseResult)) {
logger.warn('Invalid request in getRepoCoordinates', { reason: parseResult.reason })
return failedWithResult('Failed to parse', invalidRequestResponse)
Expand All @@ -32,4 +32,4 @@ export const repoCoordinatesSchema: JTDSchemaType<RepoCoordinatesQueryStringPara
}
}

const qsParser = validatingQueryStringParser(repoCoordinatesSchema)
const parser = validatingQueryStringParser(repoCoordinatesSchema)
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export function getWorkflowCoordinates(
})
}

interface WorkflowCoordinatesQueryStringParameters extends RepoCoordinatesQueryStringParameters {
export interface WorkflowCoordinatesQueryStringParameters extends RepoCoordinatesQueryStringParameters {
workflowId: string
}

const schema: JTDSchemaType<WorkflowCoordinatesQueryStringParameters> = {
export const workflowCoordinatesSchema: JTDSchemaType<WorkflowCoordinatesQueryStringParameters> = {
properties: {
...repoCoordinatesSchema.properties,
workflowId: { type: 'string' }
}
}

const qsParser = validatingQueryStringParser(schema)
const qsParser = validatingQueryStringParser(workflowCoordinatesSchema)
Loading

0 comments on commit 1db910b

Please sign in to comment.