Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
529 changes: 529 additions & 0 deletions src/location/LOCATION_API_DOCUMENTATION.md

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions src/location/dto/location-hierarchy-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';

export class LocationItemDto {
@ApiProperty({ description: 'Location ID', example: '27' })
@Expose()
id: number;

@ApiProperty({ description: 'Location name', example: 'West Bengal' })
@Expose()
name: string;

@ApiProperty({
description: 'Location type',
enum: ['state', 'district', 'block', 'village'],
example: 'state'
})
@Expose()
type: 'state' | 'district' | 'block' | 'village';

@ApiProperty({ description: 'Parent location ID', example: '10', required: false })
@Expose()
parent_id?: number;

@ApiProperty({ description: 'Whether location is active', example: 1, required: false })
@Expose()
is_active?: number;

@ApiProperty({ description: 'Whether location is found in census', example: 1 })
@Expose()
is_found_in_census: number;

// Optional fields that exist only for state
@ApiProperty({ description: 'State code (only for states)', example: 'WB', required: false })
@Expose()
state_code?: string;
}

export class LocationHierarchyResponseDto {
@ApiProperty({ description: 'Success status', example: true })
@Expose()
success: boolean;

@ApiProperty({ description: 'Response message', example: 'Hierarchy search completed successfully' })
@Expose()
message: string;

@ApiProperty({
description: 'Array of location items matching the search criteria',
type: [LocationItemDto]
})
@Expose()
data: LocationItemDto[];

@ApiProperty({ description: 'Total count of results', example: 25 })
@Expose()
totalCount: number;

@ApiProperty({
description: 'Search parameters used for the query',
example: {
id: '27',
type: 'state',
direction: 'child',
target: ['village'],
keyword: 'Naba'
}
})
@Expose()
searchParams: {
id: string;
type: string;
direction: string;
target?: string[];
keyword?: string;
};
}
76 changes: 76 additions & 0 deletions src/location/dto/location-hierarchy-search.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
IsString,
IsNotEmpty,
IsIn,
IsOptional,
IsArray,
ArrayMinSize,
ValidateIf
} from 'class-validator';
import { Expose } from 'class-transformer';

export class LocationHierarchySearchDto {
@ApiProperty({
description: 'ID of the location entity to start the hierarchy search from',
example: '27',
type: String
})
@Expose()
@IsNotEmpty({ message: 'ID is required' })
@IsString({ message: 'ID must be a string' })
id: string;

@ApiProperty({
description: 'Type of the location entity corresponding to the provided ID',
enum: ['state', 'district', 'block', 'village'],
example: 'state'
})
@Expose()
@IsNotEmpty({ message: 'Type is required' })
@IsString({ message: 'Type must be a string' })
@IsIn(['state', 'district', 'block', 'village'], {
message: 'Type must be one of: state, district, block, village'
})
type: 'state' | 'district' | 'block' | 'village';

@ApiProperty({
description: 'Direction of hierarchy traversal',
enum: ['child', 'parent'],
example: 'child'
})
@Expose()
@IsNotEmpty({ message: 'Direction is required' })
@IsString({ message: 'Direction must be a string' })
@IsIn(['child', 'parent'], {
message: 'Direction must be either "child" or "parent"'
})
direction: 'child' | 'parent';

@ApiPropertyOptional({
description: 'Specific target levels to return in the hierarchy. If not provided, returns all levels in the direction.',
type: [String],
enum: ['state', 'district', 'block', 'village'],
example: ['village']
})
@Expose()
@IsOptional()
@IsArray({ message: 'Target must be an array' })
@ArrayMinSize(1, { message: 'Target array must contain at least one element' })
@IsString({ each: true, message: 'Each target element must be a string' })
@IsIn(['state', 'district', 'block', 'village'], {
each: true,
message: 'Each target must be one of: state, district, block, village'
})
target?: ('state' | 'district' | 'block' | 'village')[];

@ApiPropertyOptional({
description: 'Keyword to search for in location names. Case-insensitive partial match.',
example: 'Naba'
})
@Expose()
@IsOptional()
@IsString({ message: 'Keyword must be a string' })
@ValidateIf(o => o.keyword !== undefined && o.keyword !== null && o.keyword !== '')
keyword?: string;
}
49 changes: 49 additions & 0 deletions src/location/entities/block.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
} from "typeorm";

@Entity({ name: "block" })
export class Block {
@PrimaryGeneratedColumn({ name: "block_id" })
block_id: number;

@Column({ type: "varchar", length: 50, nullable: true })
block_name: string;

@Column({ type: "integer", nullable: true })
district_id: number;

@Column({ type: "integer", nullable: true })
district_id_pc: number;

@Column({ type: "integer", nullable: true })
block_id_pc: number;

@Column({ type: "integer", nullable: true })
block_type: number;

@Column({ type: "varchar", length: 20, nullable: true })
block_id_finance: string;

@Column({ type: "smallint", default: 0, nullable: false })
is_found_in_census: number;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
created_at: Date;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
updated_at: Date;

@Column({ type: "smallint", default: 1, nullable: true })
is_active: number;
}
49 changes: 49 additions & 0 deletions src/location/entities/district.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
} from "typeorm";

@Entity({ name: "district" })
export class District {
@PrimaryGeneratedColumn({ name: "district_id" })
district_id: number;

@Column({ type: "varchar", length: 40, nullable: true })
district_name: string;

@Column({ type: "integer", nullable: true })
state_id: number;

@Column({ type: "integer", nullable: true })
state_id_pc: number;

@Column({ type: "integer", nullable: true })
district_id_pc: number;

@Column({ type: "varchar", length: 20, nullable: true })
district_id_finance: string;

@Column({ type: "smallint", default: 0, nullable: false })
is_found_in_census: number;

@Column({ type: "varchar", length: 30, nullable: true })
old_district_name: string;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
created_at: Date;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
updated_at: Date;

@Column({ type: "smallint", default: 1, nullable: true })
is_active: number;
}
43 changes: 43 additions & 0 deletions src/location/entities/state.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
Entity,
PrimaryColumn,
Column,
} from "typeorm";

@Entity({ name: "state" })
export class State {
@PrimaryColumn({ type: "integer" })
state_id: number;

@Column({ type: "varchar", length: 50, nullable: true })
state_name: string;

@Column({ type: "char", length: 2, nullable: true })
state_code: string;

@Column({ type: "integer", nullable: true })
state_id_pc: number;

@Column({ type: "varchar", length: 20, nullable: true })
state_id_finance: string;

@Column({ type: "smallint", default: 0, nullable: false })
is_found_in_census: number;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
created_at: Date;

@Column({
type: "timestamp",
default: () => "CURRENT_TIMESTAMP",
nullable: false
})
updated_at: Date;

@Column({ type: "smallint", default: 1, nullable: true })
is_active: number;
}
35 changes: 35 additions & 0 deletions src/location/entities/village.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
} from "typeorm";

@Entity({ name: "village" })
export class Village {
@PrimaryGeneratedColumn({ name: "village_id" })
village_id: number;

@Column({ type: "varchar", length: 250, nullable: true })
village_name: string;

@Column({ type: "integer", nullable: true })
block_id: number;

@Column({ type: "integer", nullable: true })
pc_block_id: number;

@Column({ type: "integer", nullable: true })
pc_village_id: number;

@Column({ type: "integer", nullable: true })
created_by: number;

@Column({ type: "smallint", default: 0, nullable: false })
is_found_in_census: number;

@Column({ type: "smallint", default: 1, nullable: false })
community_type: number;

@Column({ type: "smallint", nullable: true })
is_active: number;
}
Loading