Skip to content
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

chore: rearrange directory structure #1606

Merged
merged 8 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ identities, and E-mail servers hosted in Government Data Centres.

## Backend

FormSG is currently in the process of migrating its backend to TypeScript, so you will find
a mixture of `.js` and `.ts` files in the backend.

The backend for FormSG is bootstrapped using `src/server.ts` and `src/loaders`.
It sets up express.js routes defined in `src/app/routes/*.(j|t)s`, with business logic
defined in `src/app/controllers/*.(j|t)s` and mongoose models defined in `src/app/models/*.(j|t)s`.
The backend for FormSG is bootstrapped using `src/server.ts` and `src/app/loaders`.
It sets up express.js routes defined in `src/app/**/*.routes.ts`, with business logic
defined in `src/app/**/*.controller.ts` and mongoose models defined in `src/app/**/*.model.ts`.

### Security

Expand Down
8 changes: 7 additions & 1 deletion src/config/config.ts → src/app/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import nodemailer from 'nodemailer'
import Mail from 'nodemailer/lib/mailer'
import SMTPPool from 'nodemailer/lib/smtp-pool'

import { AwsConfig, Config, DbConfig, Environment, MailConfig } from '../types'
import {
AwsConfig,
Config,
DbConfig,
Environment,
MailConfig,
} from '../../types'

import {
compulsoryVarsSchema,
Expand Down
2 changes: 1 addition & 1 deletion src/config/formsg-sdk.ts → src/app/config/formsg-sdk.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import formsgSdkPackage from '@opengovsg/formsg-sdk'
import { get } from 'lodash'

import * as vfnConstants from '../shared/util/verification'
import * as vfnConstants from '../../shared/util/verification'

import { formsgSdkMode } from './config'
import featureManager, { FeatureNames } from './feature-manager'
Expand Down
2 changes: 1 addition & 1 deletion src/config/logger.ts → src/app/config/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { v4 as uuidv4 } from 'uuid'
import { format, Logger, LoggerOptions, loggers, transports } from 'winston'
import WinstonCloudWatch from 'winston-cloudwatch'

import { Environment } from '../types'
import { Environment } from '../../types'

import { aws, customCloudWatchGroup, isDev, nodeEnv } from './config'

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/config/schema.ts → src/app/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
ICompulsoryVarsSchema,
IOptionalVarsSchema,
IProdOnlyVarsSchema,
} from '../types'
} from '../../types'

convict.addFormat(url)
convict.addFormat(email)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import helmet from 'helmet'
import { mocked } from 'ts-jest/utils'

import config from 'src/config/config'
import featureManager from 'src/config/feature-manager'
import config from 'src/app/config/config'
import featureManager from 'src/app/config/feature-manager'

import expressHandler from 'tests/unit/backend/helpers/jest-express'

Expand All @@ -11,9 +11,9 @@ import helmetMiddlewares from '../helmet'
describe('helmetMiddlewares', () => {
jest.mock('helmet')
const mockHelmet = mocked(helmet, true)
jest.mock('src/config/feature-manager')
jest.mock('src/app/config/feature-manager')
const mockFeatureManager = mocked(featureManager, true)
jest.mock('src/config/config')
jest.mock('src/app/config/config')
const mockConfig = mocked(config, true)

const cspCoreDirectives = {
Expand Down
File renamed without changes.
36 changes: 18 additions & 18 deletions src/loaders/express/index.ts → src/app/loaders/express/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ import nocache from 'nocache'
import path from 'path'
import url from 'url'

import { AnalyticsRouter } from '../../app/modules/analytics/analytics.routes'
import { AuthRouter } from '../../app/modules/auth/auth.routes'
import { BillingRouter } from '../../app/modules/billing/billing.routes'
import { BounceRouter } from '../../app/modules/bounce/bounce.routes'
import { ExamplesRouter } from '../../app/modules/examples/examples.routes'
import { AdminFormsRouter } from '../../app/modules/form/admin-form/admin-form.routes'
import { PublicFormRouter } from '../../app/modules/form/public-form/public-form.routes'
import { FrontendRouter } from '../../app/modules/frontend/frontend.server.routes'
import { HomeRouter } from '../../app/modules/home/home.routes'
import { MYINFO_ROUTER_PREFIX } from '../../app/modules/myinfo/myinfo.constants'
import { MyInfoRouter } from '../../app/modules/myinfo/myinfo.routes'
import config from '../../config/config'
import { AnalyticsRouter } from '../../modules/analytics/analytics.routes'
import { AuthRouter } from '../../modules/auth/auth.routes'
import { BillingRouter } from '../../modules/billing/billing.routes'
import { BounceRouter } from '../../modules/bounce/bounce.routes'
import { ExamplesRouter } from '../../modules/examples/examples.routes'
import { AdminFormsRouter } from '../../modules/form/admin-form/admin-form.routes'
import { PublicFormRouter } from '../../modules/form/public-form/public-form.routes'
import { FrontendRouter } from '../../modules/frontend/frontend.routes'
import { HomeRouter } from '../../modules/home/home.routes'
import { MYINFO_ROUTER_PREFIX } from '../../modules/myinfo/myinfo.constants'
import { MyInfoRouter } from '../../modules/myinfo/myinfo.routes'
import {
CorppassLoginRouter,
SingpassLoginRouter,
SpcpRouter,
} from '../../app/modules/spcp/spcp.routes'
import { SubmissionRouter } from '../../app/modules/submission/submission.routes'
import UserRouter from '../../app/modules/user/user.routes'
import { VfnRouter } from '../../app/modules/verification/verification.routes'
import { ApiRouter } from '../../app/routes/api'
import * as IntranetMiddleware from '../../app/services/intranet/intranet.middleware'
import config from '../../config/config'
} from '../../modules/spcp/spcp.routes'
import { SubmissionRouter } from '../../modules/submission/submission.routes'
import UserRouter from '../../modules/user/user.routes'
import { VfnRouter } from '../../modules/verification/verification.routes'
import { ApiRouter } from '../../routes/api'
import * as IntranetMiddleware from '../../services/intranet/intranet.middleware'

import errorHandlerMiddlewares from './error-handler'
import helmetMiddlewares from './helmet'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import expressWinston from 'express-winston'
import get from 'lodash/get'
import winston from 'winston'

import { getRequestIp, getTrace } from '../../app/utils/request'
import config from '../../config/config'
import { customFormat } from '../../config/logger'
import { getRequestIp, getTrace } from '../../utils/request'

const LOGGER_LABEL = 'network'

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
UpsertOtpParams,
} from 'src/types/admin_verification'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const AdminVerification = getAdminVerificationModel(mongoose)

Expand Down Expand Up @@ -87,7 +87,6 @@ describe('AdminVerification Model', () => {
}

// Act
// @ts-ignore
const actualPromise = AdminVerification.create(missingContactParams)

// Assert
Expand All @@ -104,7 +103,6 @@ describe('AdminVerification Model', () => {
}

// Act
// @ts-ignore
const actualPromise = AdminVerification.create(missingOtpParams)

// Assert
Expand All @@ -121,7 +119,6 @@ describe('AdminVerification Model', () => {
}

// Act
// @ts-ignore
const actualPromise = AdminVerification.create(missingExpireParams)

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import getAgencyModel, {
AGENCY_PUBLIC_FIELDS,
} from 'src/app/models/agency.server.model'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const Agency = getAgencyModel(mongoose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
SubmissionType,
} from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const Submission = getSubmissionModel(mongoose)
const EncryptSubmission = getEncryptSubmissionModel(mongoose)
Expand All @@ -33,16 +33,16 @@ describe('Encrypt Submission Model', () => {
const validFormId = new ObjectId().toHexString()
const createdDate = new Date()
// Add valid encrypt submission.
const validSubmission = await Submission.create<
IEncryptedSubmissionSchema
>({
form: validFormId,
myInfoFields: [],
submissionType: SubmissionType.Encrypt,
encryptedContent: MOCK_ENCRYPTED_CONTENT,
version: 1,
created: createdDate,
})
const validSubmission = await Submission.create<IEncryptedSubmissionSchema>(
{
form: validFormId,
myInfoFields: [],
submissionType: SubmissionType.Encrypt,
encryptedContent: MOCK_ENCRYPTED_CONTENT,
version: 1,
created: createdDate,
},
)

// Act
const result = await EncryptSubmission.findSingleMetadata(
Expand Down Expand Up @@ -391,15 +391,15 @@ describe('Encrypt Submission Model', () => {
it('should return null when type of submission with given id is not SubmissionType.Encrypt', async () => {
// Arrange
const validFormId = new ObjectId().toHexString()
const validEmailSubmission = await Submission.create<
IEmailSubmissionSchema
>({
submissionType: SubmissionType.Email,
form: validFormId,
recipientEmails: ['any@example.com'],
responseHash: 'any hash',
responseSalt: 'any salt',
})
const validEmailSubmission = await Submission.create<IEmailSubmissionSchema>(
{
submissionType: SubmissionType.Email,
form: validFormId,
recipientEmails: ['[email protected]'],
responseHash: 'any hash',
responseSalt: 'any salt',
},
)

// Act
const actual = await EncryptSubmission.findEncryptedSubmissionById(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
Status,
} from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const Form = getFormModel(mongoose)
const EncryptedForm = getEncryptedFormModel(mongoose)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mongoose from 'mongoose'
import getFormFeedbackModel from 'src/app/models/form_feedback.server.model'
import { IFormFeedback } from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const FeedbackModel = getFormFeedbackModel(mongoose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mongoose from 'mongoose'
import getFormModel from 'src/app/models/form.server.model'
import { BasicField, IFieldSchema, ResponseMode } from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const Form = getFormModel(mongoose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mongoose from 'mongoose'
import getFormStatisticsTotalModel from 'src/app/models/form_statistics_total.server.model'
import { AggregateFormCountResult, IFormStatisticsTotalSchema } from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const FormStatsModel = getFormStatisticsTotalModel(mongoose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
IUserSchema,
} from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const LoginModel = getLoginModel(mongoose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import getSubmissionModel, {
getEncryptSubmissionModel,
} from 'src/app/models/submission.server.model'

import dbHandler from 'tests/unit/backend/helpers/jest-db'

import {
AuthType,
ISubmissionSchema,
IWebhookResponse,
SubmissionType,
} from '../../../../src/types'
import dbHandler from '../helpers/jest-db'

const Submission = getSubmissionModel(mongoose)
const EncryptedSubmission = getEncryptSubmissionModel(mongoose)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mongoose from 'mongoose'
import getUserModel from 'src/app/models/user.server.model'
import { IAgencySchema, IUser, IUserSchema } from 'src/types'

import dbHandler from '../helpers/jest-db'
import dbHandler from 'tests/unit/backend/helpers/jest-db'

const User = getUserModel(mongoose)

Expand Down
2 changes: 1 addition & 1 deletion src/app/models/field/imageField.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Schema } from 'mongoose'
import validator from 'validator'

import { isDev } from '../../../config/config'
import { IImageFieldSchema } from '../../../types'
import { isDev } from '../../config/config'

const createImageFieldSchema = () => {
return new Schema<IImageFieldSchema>({
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/analytics/analytics.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { StatusCodes } from 'http-status-codes'

import { AnalyticStatsDto } from 'src/types/analytics'

import { createLoggerWithLabel } from '../../../config/logger'
import { createLoggerWithLabel } from '../../config/logger'
import { createReqMeta } from '../../utils/request'

import {
Expand Down
4 changes: 2 additions & 2 deletions src/app/modules/analytics/analytics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as TE from 'fp-ts/TaskEither'
import mongoose from 'mongoose'

import { getMongoErrorMessage } from '../../../app/utils/handle-mongo-error'
import { submissionsTopUp } from '../../../config/config'
import { createLoggerWithLabel } from '../../../config/logger'
import { submissionsTopUp } from '../../config/config'
import { createLoggerWithLabel } from '../../config/logger'
import getFormModel from '../../models/form.server.model'
import getSubmissionModel from '../../models/submission.server.model'
import getUserModel from '../../models/user.server.model'
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ParamsDictionary } from 'express-serve-static-core'
import { StatusCodes } from 'http-status-codes'
import { isEmpty } from 'lodash'

import { createLoggerWithLabel } from '../../../config/logger'
import { LINKS } from '../../../shared/constants'
import { createLoggerWithLabel } from '../../config/logger'
import MailService from '../../services/mail/mail.service'
import { createReqMeta, getRequestIp } from '../../utils/request'
import * as UserService from '../user/user.service'
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/auth/auth.routes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { celebrate, Joi, Segments } from 'celebrate'
import { Router } from 'express'

import { rateLimitConfig } from '../../../config/config'
import { rateLimitConfig } from '../../config/config'
import { limitRate } from '../../utils/limit-rate'

import * as AuthController from './auth.controller'
Expand Down
4 changes: 2 additions & 2 deletions src/app/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import mongoose from 'mongoose'
import { errAsync, okAsync, ResultAsync } from 'neverthrow'
import validator from 'validator'

import config from '../../../config/config'
import { createLoggerWithLabel } from '../../../config/logger'
import { LINKS } from '../../../shared/constants'
import {
IAgencySchema,
IPopulatedForm,
ITokenSchema,
IUserSchema,
} from '../../../types'
import config from '../../config/config'
import { createLoggerWithLabel } from '../../config/logger'
import getAgencyModel from '../../models/agency.server.model'
import getTokenModel from '../../models/token.server.model'
import { compareHash, HashingError } from '../../utils/hash'
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/auth/auth.utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { StatusCodes } from 'http-status-codes'

import { createLoggerWithLabel } from '../../../config/logger'
import { MapRouteError } from '../../../types/routing'
import { createLoggerWithLabel } from '../../config/logger'
import * as MailErrors from '../../services/mail/mail.errors'
import { HashingError } from '../../utils/hash'
import * as CoreErrors from '../core/core.errors'
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/billing/__tests__/billing.factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
FeatureNames,
ISpcpMyInfo,
RegisteredFeature,
} from 'src/config/feature-manager'
} from 'src/app/config/feature-manager'
import {
AuthType,
ILoginSchema,
Expand Down
Loading