Skip to content

Commit

Permalink
250 implementation of city council district (ccd) endpoint
Browse files Browse the repository at this point in the history
 - ccd controller, module, repository, service
 - cd unit and e2e tests
 - indentation fixes on openapi yaml
 - tweaks to README
 - regen ts and zod schemas
  • Loading branch information
horatiorosa committed May 31, 2024
1 parent 832b208 commit 249b9e9
Show file tree
Hide file tree
Showing 25 changed files with 294 additions and 65 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ Finally, to run the api locally:
npm run dev
```

- View the documentation locally through port 3000
- To use the API locally, append `/api/{endpoint_route}` to the port (ex: `/api/boroughs`)

(This command will also create a static site of the OpenAPI documentation at the root of the API.
This site reflects the documentation at the point where the command was written. Viewing changes to
the OpenAPI documentation requires restarting the development server).
Expand Down
4 changes: 4 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ services:
- POSTGRES_DB=${DATABASE_NAME}
ports:
- "8010:5432"
networks:
- data
volumes:
- ./db-volume:/var/lib/postgresql/data
networks:
data:
24 changes: 12 additions & 12 deletions openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -664,15 +664,15 @@ components:
type: number
description: A numeric string used to refer to the amount of total planned commitments.
example: 1600000
required:
- id
- type
- plannedDate
- budgetLineCode
- budgetLineId
- sponsoringAgencyInitials
- budgetType
- totalValue
required:
- id
- type
- plannedDate
- budgetLineCode
- budgetLineId
- sponsoringAgencyInitials
- budgetType
- totalValue
CapitalProjectCategory:
type: string
enum:
Expand Down Expand Up @@ -779,9 +779,9 @@ components:
description: A single character numeric string containing the common number used to refer to the borough. Possible values are 1-5.
pattern: \b[1-9]\b
example: 1
required:
- id
- boroughId
required:
- id
- boroughId
LandUse:
type: object
properties:
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { DbConfig, FeatureFlagConfig, StorageConfig } from "./config";
import { GlobalModule } from "./global/global.module";
import { ZoningDistrictClassModule } from "./zoning-district-class/zoning-district-class.module";
import { AgencyModule } from "./agency/agency.module";
import { CityCouncilDistrictModule } from "./city-council-district/city-council-district.module";

@Module({
imports: [
Expand All @@ -39,6 +40,7 @@ import { AgencyModule } from "./agency/agency.module";
GlobalModule,
AgencyModule,
BoroughModule,
CityCouncilDistrictModule,
LandUseModule,
TaxLotModule,
ZoningDistrictModule,
Expand Down
16 changes: 16 additions & 0 deletions src/city-council-district/city-council-district.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Controller, Get, UseFilters } from "@nestjs/common";
import { CityCouncilDistrictService } from "./city-council-district.service";
import { InternalServerErrorExceptionFilter } from "src/filter";

@UseFilters(InternalServerErrorExceptionFilter)
@Controller("city-council-districts")
export class CityCouncilDistrictController {
constructor(
private readonly cityCouncilDistrictService: CityCouncilDistrictService,
) {}

@Get()
async findMany() {
return this.cityCouncilDistrictService.findMany();
}
}
11 changes: 11 additions & 0 deletions src/city-council-district/city-council-district.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from "@nestjs/common";
import { CityCouncilDistrictService } from "./city-council-district.service";
import { CityCouncilDistrictController } from "./city-council-district.controller";
import { CityCouncilDistrictRepository } from "./city-council-district.repository";

@Module({
exports: [CityCouncilDistrictService],
providers: [CityCouncilDistrictService, CityCouncilDistrictRepository],
controllers: [CityCouncilDistrictController],
})
export class CityCouncilDistrictModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { cityCouncilDistrictEntitySchema } from "src/schema";
import { z } from "zod";

export const findManyRepoSchema = z.array(cityCouncilDistrictEntitySchema);

export type FindManyRepo = z.infer<typeof findManyRepoSchema>;
24 changes: 24 additions & 0 deletions src/city-council-district/city-council-district.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Inject } from "@nestjs/common";
import { DB, DbType } from "src/global/providers/db.provider";
import { DataRetrievalException } from "src/exception";
import { FindManyRepo } from "./city-council-district.repository.schema";

export class CityCouncilDistrictRepository {
constructor(
@Inject(DB)
private readonly db: DbType,
) {}

async findMany(): Promise<FindManyRepo> {
try {
return await this.db.query.cityCouncilDistrict.findMany({
columns: {
id: true,
liFt: false,
},
});
} catch {
throw new DataRetrievalException();
}
}
}
32 changes: 32 additions & 0 deletions src/city-council-district/city-council-district.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { CityCouncilDistrictRepositoryMock } from "test/city-council-district/city-council-district.repository.mock";
import { Test } from "@nestjs/testing";
import { CityCouncilDistrictRepository } from "./city-council-district.repository";
import { findCityCouncilDistrictsQueryResponseSchema } from "src/gen";
import { CityCouncilDistrictService } from "./city-council-district.service";

describe("City Council District service unit", () => {
let cityCouncilDistrictService: CityCouncilDistrictService;

beforeEach(async () => {
const cityCouncilDistrictRepositoryMock =
new CityCouncilDistrictRepositoryMock();

const moduleRef = await Test.createTestingModule({
providers: [CityCouncilDistrictService, CityCouncilDistrictRepository],
})
.overrideProvider(CityCouncilDistrictRepository)
.useValue(cityCouncilDistrictRepositoryMock)
.compile();

cityCouncilDistrictService = moduleRef.get<CityCouncilDistrictService>(
CityCouncilDistrictService,
);
});

it("service should return a findCityCouncilDistrictsQueryResponseSchema compliant object", async () => {
const cityCouncilDistricts = await cityCouncilDistrictService.findMany();
expect(() =>
findCityCouncilDistrictsQueryResponseSchema.parse(cityCouncilDistricts),
).not.toThrow();
});
});
19 changes: 19 additions & 0 deletions src/city-council-district/city-council-district.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Inject, Injectable } from "@nestjs/common";
import { CityCouncilDistrictRepository } from "./city-council-district.repository";

@Injectable()
export class CityCouncilDistrictService {
constructor(
@Inject(CityCouncilDistrictRepository)
private readonly cityCouncilDistrictRepository: CityCouncilDistrictRepository,
) {}

async findMany() {
const cityCouncilDistricts =
await this.cityCouncilDistrictRepository.findMany();

return {
cityCouncilDistricts,
};
}
}
33 changes: 16 additions & 17 deletions src/gen/types/CapitalCommitment.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,49 @@
export type CapitalCommitment = {
/**
* @description A uuid used to refer to the capital commitment.
* @type string | undefined uuid
* @type string uuid
*/
id?: string;
id: string;
/**
* @description A four character string used to refer to the commitment type.
* @type string | undefined
* @type string
* @example DSGN
*/
type?: string;
type: string;
/**
* @description A string used to refer to the date when the commitment is projected to be committed.
* @type string | undefined date
* @type string date
* @example 2012-04-23
*/
plannedDate?: string;
plannedDate: string;
/**
* @description A string used to refer to the budget line.
* @type string | undefined
* @type string
* @example HW
*/
budgetLineCode?: string;
budgetLineCode: string;
/**
* @description A string used to refer to the budget line.
* @type string | undefined
* @type string
* @example 0002Q
*/
budgetLineId?: string;
budgetLineId: string;
/**
* @description A string of variable length containing the initials of the sponsoring agency.
* @type string | undefined
* @type string
* @example DOT
*/
sponsoringAgencyInitials?: string;
sponsoringAgencyInitials: string;
/**
* @description A string of variable length denoting the type of budget.
* @type string | undefined
* @type string
* @example Highways
*/
budgetType?: string;
budgetType: string;
/**
* @description A numeric string used to refer to the amount of total planned commitments.
* @type number | undefined
* @type number
* @example 1600000
*/
totalValue?: number;
required?: any;
totalValue: number;
};
12 changes: 6 additions & 6 deletions src/gen/types/CapitalProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ export type CapitalProject = {
managingAgencyInitials: string;
/**
* @description The starting date of the capital project
* @type date
* @example 2024-05-15T14:20:03.842Z
* @type string date
* @example 2024-05-15
*/
minDate: any;
minDate: string;
/**
* @description The ending date of the capital project
* @type date
* @example 2024-05-15T14:20:03.842Z
* @type string date
* @example 2024-05-15
*/
maxDate: any;
maxDate: string;
category?: CapitalProjectCategory;
};
9 changes: 9 additions & 0 deletions src/gen/types/CapitalProjectPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Page } from "./Page";
import type { CapitalProject } from "./CapitalProject";

export type CapitalProjectPage = Page & {
/**
* @type array
*/
capitalProjects: CapitalProject[];
};
9 changes: 4 additions & 5 deletions src/gen/types/CommunityDistrict.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
export type CommunityDistrict = {
/**
* @description The two character numeric string containing the number used to refer to the community district.
* @type string | undefined
* @type string
* @example 1
*/
id?: string;
id: string;
/**
* @description A single character numeric string containing the common number used to refer to the borough. Possible values are 1-5.
* @type string | undefined
* @type string
* @example 1
*/
boroughId?: string;
required?: any;
boroughId: string;
};
16 changes: 16 additions & 0 deletions src/gen/types/FindCityCouncilDistricts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Error } from "./Error";
import type { CityCouncilDistrict } from "./CityCouncilDistrict";

export type FindCityCouncilDistricts400 = Error;

export type FindCityCouncilDistricts500 = Error;

/**
* @description an object of city council districts
*/
export type FindCityCouncilDistrictsQueryResponse = {
/**
* @type array
*/
cityCouncilDistricts: CityCouncilDistrict[];
};
2 changes: 2 additions & 0 deletions src/gen/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ export * from "./CapitalCommitment";
export * from "./CapitalProject";
export * from "./CapitalProjectBudgeted";
export * from "./CapitalProjectCategory";
export * from "./CapitalProjectPage";
export * from "./CityCouncilDistrict";
export * from "./CommunityDistrict";
export * from "./Error";
export * from "./FindAgencies";
export * from "./FindBoroughs";
export * from "./FindCityCouncilDistricts";
export * from "./FindCommunityDistrictsByBoroughId";
export * from "./FindLandUses";
export * from "./FindTaxLotByBbl";
Expand Down
25 changes: 8 additions & 17 deletions src/gen/zod/capitalCommitmentSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,33 @@ export const capitalCommitmentSchema = z.object({
id: z
.string()
.describe(`A uuid used to refer to the capital commitment.`)
.uuid()
.optional(),
.uuid(),
type: z
.string()
.describe(`A four character string used to refer to the commitment type.`)
.regex(new RegExp("^([A-z]{4})$"))
.optional(),
.regex(new RegExp("^([A-z]{4})$")),
plannedDate: z
.string()
.describe(
`A string used to refer to the date when the commitment is projected to be committed.`,
)
.optional(),
),
budgetLineCode: z
.string()
.describe(`A string used to refer to the budget line.`)
.optional(),
.describe(`A string used to refer to the budget line.`),
budgetLineId: z
.string()
.describe(`A string used to refer to the budget line.`)
.optional(),
.describe(`A string used to refer to the budget line.`),
sponsoringAgencyInitials: z
.string()
.describe(
`A string of variable length containing the initials of the sponsoring agency.`,
)
.optional(),
),
budgetType: z
.string()
.describe(`A string of variable length denoting the type of budget.`)
.optional(),
.describe(`A string of variable length denoting the type of budget.`),
totalValue: z
.number()
.describe(
`A numeric string used to refer to the amount of total planned commitments.`,
)
.optional(),
required: z.any().optional(),
),
});
Loading

0 comments on commit 249b9e9

Please sign in to comment.