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

250 Implement findCityCouncilDistricts endpoint #302

Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ Finally, to run the api locally:
npm run dev
```

The application is running on port `3000`
- The root route `/` has the documentation built from the point where the application was run (`localhost:3000/`)
- The `/api/{endpoint}` routes have the actual API implementation (ex: `localhost:3000/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
2 changes: 1 addition & 1 deletion openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ paths:
$ref: '#/components/responses/InternalServerError'
/city-council-districts:
horatiorosa marked this conversation as resolved.
Show resolved Hide resolved
get:
summary: 🚧 Find city council districts
summary: Find city council districts
operationId: findCityCouncilDistricts
tags:
- City Council Districts
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>;
23 changes: 23 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,23 @@
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,
},
});
} 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(),
),
});
12 changes: 12 additions & 0 deletions src/gen/zod/capitalProjectPageSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { z } from "zod";

import { pageSchema } from "./pageSchema";
import { capitalProjectSchema } from "./capitalProjectSchema";

export const capitalProjectPageSchema = z
.lazy(() => pageSchema)
.schema.and(
z.object({
capitalProjects: z.array(z.lazy(() => capitalProjectSchema).schema),
}),
);
4 changes: 2 additions & 2 deletions src/gen/zod/capitalProjectSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const capitalProjectSchema = z.object({
managingAgencyInitials: z
.string()
.describe(`The managing agency name abbreviation or acronym`),
minDate: z.any().describe(`The starting date of the capital project`),
maxDate: z.any().describe(`The ending date of the capital project`),
minDate: z.string().describe(`The starting date of the capital project`),
maxDate: z.string().describe(`The ending date of the capital project`),
category: z.lazy(() => capitalProjectCategorySchema).schema.optional(),
});
7 changes: 2 additions & 5 deletions src/gen/zod/communityDistrictSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ export const communityDistrictSchema = z.object({
.describe(
`The two character numeric string containing the number used to refer to the community district.`,
)
.regex(new RegExp("^([0-9]{2})$"))
.optional(),
.regex(new RegExp("^([0-9]{2})$")),
boroughId: z
.string()
.describe(
`A single character numeric string containing the common number used to refer to the borough. Possible values are 1-5.`,
)
.regex(new RegExp("\\b[1-9]\\b"))
.optional(),
required: z.any().optional(),
.regex(new RegExp("\\b[1-9]\\b")),
});
Loading