🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

View File

@@ -0,0 +1,9 @@
export declare class FindNearbyParkingDto {
lat: number;
lng: number;
radius?: number;
maxResults?: number;
priceRange?: [number, number];
amenities?: string[];
availabilityFilter?: 'available' | 'limited' | 'full';
}

View File

@@ -0,0 +1,112 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FindNearbyParkingDto = void 0;
const swagger_1 = require("@nestjs/swagger");
const class_validator_1 = require("class-validator");
const class_transformer_1 = require("class-transformer");
class FindNearbyParkingDto {
constructor() {
this.radius = 4000;
this.maxResults = 20;
}
}
exports.FindNearbyParkingDto = FindNearbyParkingDto;
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Latitude coordinate',
example: 1.3521,
minimum: -90,
maximum: 90
}),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(-90),
(0, class_validator_1.Max)(90),
(0, class_transformer_1.Transform)(({ value }) => parseFloat(value)),
__metadata("design:type", Number)
], FindNearbyParkingDto.prototype, "lat", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Longitude coordinate',
example: 103.8198,
minimum: -180,
maximum: 180
}),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(-180),
(0, class_validator_1.Max)(180),
(0, class_transformer_1.Transform)(({ value }) => parseFloat(value)),
__metadata("design:type", Number)
], FindNearbyParkingDto.prototype, "lng", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Search radius in meters',
example: 4000,
minimum: 100,
maximum: 10000,
required: false
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(100),
(0, class_validator_1.Max)(10000),
(0, class_transformer_1.Transform)(({ value }) => parseFloat(value)),
__metadata("design:type", Number)
], FindNearbyParkingDto.prototype, "radius", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Maximum number of results to return',
example: 20,
minimum: 1,
maximum: 100,
required: false
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(1),
(0, class_validator_1.Max)(100),
(0, class_transformer_1.Transform)(({ value }) => parseInt(value)),
__metadata("design:type", Number)
], FindNearbyParkingDto.prototype, "maxResults", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Price range filter [min, max] per hour',
example: [0, 10],
required: false,
type: [Number]
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsArray)(),
(0, class_validator_1.IsNumber)({}, { each: true }),
__metadata("design:type", Array)
], FindNearbyParkingDto.prototype, "priceRange", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Required amenities',
example: ['covered', 'security', 'ev_charging'],
required: false,
type: [String]
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsArray)(),
__metadata("design:type", Array)
], FindNearbyParkingDto.prototype, "amenities", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Filter by availability status',
example: 'available',
enum: ['available', 'limited', 'full'],
required: false
}),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], FindNearbyParkingDto.prototype, "availabilityFilter", void 0);
//# sourceMappingURL=find-nearby-parking.dto.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"find-nearby-parking.dto.js","sourceRoot":"","sources":["../../../../src/modules/parking/dto/find-nearby-parking.dto.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,6 @@
export declare class UpdateParkingAvailabilityDto {
availableSlots: number;
source?: string;
confidence?: number;
metadata?: Record<string, any>;
}

View File

@@ -0,0 +1,65 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateParkingAvailabilityDto = void 0;
const swagger_1 = require("@nestjs/swagger");
const class_validator_1 = require("class-validator");
class UpdateParkingAvailabilityDto {
constructor() {
this.source = 'manual';
this.confidence = 1.0;
}
}
exports.UpdateParkingAvailabilityDto = UpdateParkingAvailabilityDto;
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Number of available parking slots',
example: 15,
minimum: 0
}),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(0),
__metadata("design:type", Number)
], UpdateParkingAvailabilityDto.prototype, "availableSlots", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Source of the update',
example: 'sensor',
required: false
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsString)(),
__metadata("design:type", String)
], UpdateParkingAvailabilityDto.prototype, "source", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Confidence level of the update (0-1)',
example: 0.95,
minimum: 0,
maximum: 1,
required: false
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(0),
(0, class_validator_1.Max)(1),
__metadata("design:type", Number)
], UpdateParkingAvailabilityDto.prototype, "confidence", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
description: 'Additional metadata',
example: { sensor_id: 'PARK_001', battery_level: 85 },
required: false
}),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Object)
], UpdateParkingAvailabilityDto.prototype, "metadata", void 0);
//# sourceMappingURL=update-availability.dto.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"update-availability.dto.js","sourceRoot":"","sources":["../../../../src/modules/parking/dto/update-availability.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA2E;AAE3E,MAAa,4BAA4B;IAAzC;QAiBE,WAAM,GAAY,QAAQ,CAAC;QAa3B,eAAU,GAAY,GAAG,CAAC;IAS5B,CAAC;CAAA;AAvCD,oEAuCC;AA/BC;IAPC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,CAAC;KACX,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,CAAC,CAAC;;oEACgB;AASvB;IAPC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,sBAAsB;QACnC,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE,KAAK;KAChB,CAAC;IACD,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;4DACgB;AAa3B;IAXC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,sCAAsC;QACnD,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,KAAK;KAChB,CAAC;IACD,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,qBAAG,EAAC,CAAC,CAAC;IACN,IAAA,qBAAG,EAAC,CAAC,CAAC;;gEACmB;AAQ1B;IANC,IAAA,qBAAW,EAAC;QACX,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,EAAE;QACrD,QAAQ,EAAE,KAAK;KAChB,CAAC;IACD,IAAA,4BAAU,GAAE;;8DACkB"}

View File

@@ -0,0 +1,13 @@
import { User } from '../../users/entities/user.entity';
import { ParkingLot } from './parking-lot.entity';
export declare class ParkingHistory {
id: number;
userId: string;
parkingLotId: number;
visitDate: Date;
durationMinutes: number;
rating: number;
review: string;
user: User;
parkingLot: ParkingLot;
}

View File

@@ -0,0 +1,68 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingHistory = void 0;
const typeorm_1 = require("typeorm");
const swagger_1 = require("@nestjs/swagger");
const user_entity_1 = require("../../users/entities/user.entity");
const parking_lot_entity_1 = require("./parking-lot.entity");
let ParkingHistory = class ParkingHistory {
};
exports.ParkingHistory = ParkingHistory;
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Unique identifier for the parking history entry' }),
(0, typeorm_1.PrimaryGeneratedColumn)(),
__metadata("design:type", Number)
], ParkingHistory.prototype, "id", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'User who visited the parking lot' }),
(0, typeorm_1.Column)({ type: 'uuid', nullable: true }),
__metadata("design:type", String)
], ParkingHistory.prototype, "userId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Parking lot that was visited' }),
(0, typeorm_1.Column)({ type: 'int' }),
__metadata("design:type", Number)
], ParkingHistory.prototype, "parkingLotId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Date and time of the visit' }),
(0, typeorm_1.CreateDateColumn)(),
__metadata("design:type", Date)
], ParkingHistory.prototype, "visitDate", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Duration of parking in minutes' }),
(0, typeorm_1.Column)({ type: 'int', nullable: true }),
__metadata("design:type", Number)
], ParkingHistory.prototype, "durationMinutes", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'User rating for the parking experience' }),
(0, typeorm_1.Column)({ type: 'int', nullable: true }),
__metadata("design:type", Number)
], ParkingHistory.prototype, "rating", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'User review comments' }),
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
__metadata("design:type", String)
], ParkingHistory.prototype, "review", void 0);
__decorate([
(0, typeorm_1.ManyToOne)(() => user_entity_1.User, (user) => user.parkingHistory, { nullable: true }),
(0, typeorm_1.JoinColumn)({ name: 'userId' }),
__metadata("design:type", user_entity_1.User)
], ParkingHistory.prototype, "user", void 0);
__decorate([
(0, typeorm_1.ManyToOne)(() => parking_lot_entity_1.ParkingLot, (parkingLot) => parkingLot.history),
(0, typeorm_1.JoinColumn)({ name: 'parkingLotId' }),
__metadata("design:type", parking_lot_entity_1.ParkingLot)
], ParkingHistory.prototype, "parkingLot", void 0);
exports.ParkingHistory = ParkingHistory = __decorate([
(0, typeorm_1.Entity)('parking_history')
], ParkingHistory);
//# sourceMappingURL=parking-history.entity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking-history.entity.js","sourceRoot":"","sources":["../../../../src/modules/parking/entities/parking-history.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAOiB;AACjB,6CAA8C;AAC9C,kEAAwD;AACxD,6DAAkD;AAG3C,IAAM,cAAc,GAApB,MAAM,cAAc;CAqC1B,CAAA;AArCY,wCAAc;AAGzB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IAC/E,IAAA,gCAAsB,GAAE;;0CACd;AAIX;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAChE,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CAC1B;AAIf;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;IAC5D,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;oDACH;AAIrB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAC1D,IAAA,0BAAgB,GAAE;8BACR,IAAI;iDAAC;AAIhB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAC9D,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;uDAChB;AAIxB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,wCAAwC,EAAE,CAAC;IACtE,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CACzB;AAIf;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACpD,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CAC1B;AAKf;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,kBAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACxE,IAAA,oBAAU,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;8BACzB,kBAAI;4CAAC;AAIX;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,+BAAU,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;IAC/D,IAAA,oBAAU,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;8BACzB,+BAAU;kDAAC;yBApCZ,cAAc;IAD1B,IAAA,gBAAM,EAAC,iBAAiB,CAAC;GACb,cAAc,CAqC1B"}

View File

@@ -0,0 +1,25 @@
import { ParkingHistory } from './parking-history.entity';
import { ParkingUpdate } from './parking-update.entity';
export declare class ParkingLot {
id: number;
name: string;
address: string;
lat: number;
lng: number;
location: string;
hourlyRate: number;
openTime: string;
closeTime: string;
availableSlots: number;
totalSlots: number;
amenities: Record<string, any>;
contactInfo: Record<string, any>;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
history: ParkingHistory[];
updates: ParkingUpdate[];
get occupancyRate(): number;
get availabilityStatus(): 'available' | 'limited' | 'full';
get isOpen(): boolean;
}

View File

@@ -0,0 +1,155 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingLot = void 0;
const typeorm_1 = require("typeorm");
const swagger_1 = require("@nestjs/swagger");
const parking_history_entity_1 = require("./parking-history.entity");
const parking_update_entity_1 = require("./parking-update.entity");
let ParkingLot = class ParkingLot {
get occupancyRate() {
if (this.totalSlots === 0)
return 0;
return ((this.totalSlots - this.availableSlots) / this.totalSlots) * 100;
}
get availabilityStatus() {
const rate = this.occupancyRate;
if (rate >= 95)
return 'full';
if (rate >= 80)
return 'limited';
return 'available';
}
get isOpen() {
if (!this.openTime || !this.closeTime)
return true;
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();
const [openHour, openMin] = this.openTime.split(':').map(Number);
const [closeHour, closeMin] = this.closeTime.split(':').map(Number);
const openMinutes = openHour * 60 + openMin;
const closeMinutes = closeHour * 60 + closeMin;
return currentTime >= openMinutes && currentTime <= closeMinutes;
}
};
exports.ParkingLot = ParkingLot;
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Unique identifier for the parking lot' }),
(0, typeorm_1.PrimaryGeneratedColumn)(),
__metadata("design:type", Number)
], ParkingLot.prototype, "id", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Name of the parking lot' }),
(0, typeorm_1.Column)({ type: 'varchar', length: 255 }),
__metadata("design:type", String)
], ParkingLot.prototype, "name", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Address of the parking lot' }),
(0, typeorm_1.Column)({ type: 'text' }),
__metadata("design:type", String)
], ParkingLot.prototype, "address", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Latitude coordinate' }),
(0, typeorm_1.Column)({ type: 'double precision' }),
__metadata("design:type", Number)
], ParkingLot.prototype, "lat", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Longitude coordinate' }),
(0, typeorm_1.Column)({ type: 'double precision' }),
__metadata("design:type", Number)
], ParkingLot.prototype, "lng", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'PostGIS geography point' }),
(0, typeorm_1.Column)({
type: 'geography',
spatialFeatureType: 'Point',
srid: 4326,
nullable: true,
}),
__metadata("design:type", String)
], ParkingLot.prototype, "location", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Hourly parking rate' }),
(0, typeorm_1.Column)({ type: 'decimal', precision: 10, scale: 2, nullable: true }),
__metadata("design:type", Number)
], ParkingLot.prototype, "hourlyRate", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Opening time' }),
(0, typeorm_1.Column)({ type: 'time', nullable: true }),
__metadata("design:type", String)
], ParkingLot.prototype, "openTime", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Closing time' }),
(0, typeorm_1.Column)({ type: 'time', nullable: true }),
__metadata("design:type", String)
], ParkingLot.prototype, "closeTime", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Number of available parking spaces' }),
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
__metadata("design:type", Number)
], ParkingLot.prototype, "availableSlots", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Total number of parking spaces' }),
(0, typeorm_1.Column)({ type: 'int' }),
__metadata("design:type", Number)
], ParkingLot.prototype, "totalSlots", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Parking lot amenities' }),
(0, typeorm_1.Column)({ type: 'jsonb', default: '{}' }),
__metadata("design:type", Object)
], ParkingLot.prototype, "amenities", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Contact information' }),
(0, typeorm_1.Column)({ type: 'jsonb', default: '{}' }),
__metadata("design:type", Object)
], ParkingLot.prototype, "contactInfo", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Whether the parking lot is active' }),
(0, typeorm_1.Column)({ type: 'boolean', default: true }),
__metadata("design:type", Boolean)
], ParkingLot.prototype, "isActive", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Creation timestamp' }),
(0, typeorm_1.CreateDateColumn)(),
__metadata("design:type", Date)
], ParkingLot.prototype, "createdAt", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Last update timestamp' }),
(0, typeorm_1.UpdateDateColumn)(),
__metadata("design:type", Date)
], ParkingLot.prototype, "updatedAt", void 0);
__decorate([
(0, typeorm_1.OneToMany)(() => parking_history_entity_1.ParkingHistory, (history) => history.parkingLot),
__metadata("design:type", Array)
], ParkingLot.prototype, "history", void 0);
__decorate([
(0, typeorm_1.OneToMany)(() => parking_update_entity_1.ParkingUpdate, (update) => update.parkingLot),
__metadata("design:type", Array)
], ParkingLot.prototype, "updates", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Occupancy rate as percentage' }),
__metadata("design:type", Number),
__metadata("design:paramtypes", [])
], ParkingLot.prototype, "occupancyRate", null);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Availability status' }),
__metadata("design:type", String),
__metadata("design:paramtypes", [])
], ParkingLot.prototype, "availabilityStatus", null);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Whether the parking lot is currently open' }),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [])
], ParkingLot.prototype, "isOpen", null);
exports.ParkingLot = ParkingLot = __decorate([
(0, typeorm_1.Entity)('parking_lots')
], ParkingLot);
//# sourceMappingURL=parking-lot.entity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking-lot.entity.js","sourceRoot":"","sources":["../../../../src/modules/parking/entities/parking-lot.entity.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,11 @@
import { ParkingLot } from './parking-lot.entity';
export declare class ParkingUpdate {
id: number;
parkingLotId: number;
availableSlots: number;
source: string;
confidence: number;
metadata: Record<string, any>;
timestamp: Date;
parkingLot: ParkingLot;
}

View File

@@ -0,0 +1,62 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingUpdate = void 0;
const typeorm_1 = require("typeorm");
const swagger_1 = require("@nestjs/swagger");
const parking_lot_entity_1 = require("./parking-lot.entity");
let ParkingUpdate = class ParkingUpdate {
};
exports.ParkingUpdate = ParkingUpdate;
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Unique identifier for the parking update' }),
(0, typeorm_1.PrimaryGeneratedColumn)(),
__metadata("design:type", Number)
], ParkingUpdate.prototype, "id", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Parking lot being updated' }),
(0, typeorm_1.Column)({ type: 'int' }),
__metadata("design:type", Number)
], ParkingUpdate.prototype, "parkingLotId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Number of available slots at time of update' }),
(0, typeorm_1.Column)({ type: 'int' }),
__metadata("design:type", Number)
], ParkingUpdate.prototype, "availableSlots", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Source of the update' }),
(0, typeorm_1.Column)({ type: 'varchar', length: 50, default: 'sensor' }),
__metadata("design:type", String)
], ParkingUpdate.prototype, "source", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Confidence level of the update (0-1)' }),
(0, typeorm_1.Column)({ type: 'decimal', precision: 3, scale: 2, default: 1.0 }),
__metadata("design:type", Number)
], ParkingUpdate.prototype, "confidence", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Additional metadata for the update' }),
(0, typeorm_1.Column)({ type: 'jsonb', default: '{}' }),
__metadata("design:type", Object)
], ParkingUpdate.prototype, "metadata", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ description: 'Timestamp of the update' }),
(0, typeorm_1.CreateDateColumn)(),
__metadata("design:type", Date)
], ParkingUpdate.prototype, "timestamp", void 0);
__decorate([
(0, typeorm_1.ManyToOne)(() => parking_lot_entity_1.ParkingLot, (parkingLot) => parkingLot.updates),
(0, typeorm_1.JoinColumn)({ name: 'parkingLotId' }),
__metadata("design:type", parking_lot_entity_1.ParkingLot)
], ParkingUpdate.prototype, "parkingLot", void 0);
exports.ParkingUpdate = ParkingUpdate = __decorate([
(0, typeorm_1.Entity)('parking_updates')
], ParkingUpdate);
//# sourceMappingURL=parking-update.entity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking-update.entity.js","sourceRoot":"","sources":["../../../../src/modules/parking/entities/parking-update.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAOiB;AACjB,6CAA8C;AAC9C,6DAAkD;AAG3C,IAAM,aAAa,GAAnB,MAAM,aAAa;CAiCzB,CAAA;AAjCY,sCAAa;AAGxB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;IACxE,IAAA,gCAAsB,GAAE;;yCACd;AAIX;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;IACzD,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;mDACH;AAIrB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IAC3E,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;qDACD;AAIvB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACpD,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;;6CAC5C;AAIf;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,sCAAsC,EAAE,CAAC;IACpE,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;;iDAC/C;AAInB;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;IAClE,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;+CACX;AAI9B;IAFC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;IACvD,IAAA,0BAAgB,GAAE;8BACR,IAAI;gDAAC;AAKhB;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,+BAAU,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;IAC/D,IAAA,oBAAU,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;8BACzB,+BAAU;iDAAC;wBAhCZ,aAAa;IADzB,IAAA,gBAAM,EAAC,iBAAiB,CAAC;GACb,aAAa,CAiCzB"}

View File

@@ -0,0 +1,22 @@
import { ParkingService } from './parking.service';
import { FindNearbyParkingDto } from './dto/find-nearby-parking.dto';
import { UpdateParkingAvailabilityDto } from './dto/update-availability.dto';
import { ParkingLot } from './entities/parking-lot.entity';
import { ParkingUpdate } from './entities/parking-update.entity';
export declare class ParkingController {
private readonly parkingService;
constructor(parkingService: ParkingService);
findNearbyParking(dto: FindNearbyParkingDto): Promise<{
parkingLots: ParkingLot[];
userLocation: {
lat: number;
lng: number;
};
searchRadius: number;
}>;
getAllParkingLots(): Promise<ParkingLot[]>;
getPopularParkingLots(limit?: number): Promise<ParkingLot[]>;
getParkingLotById(id: number): Promise<ParkingLot>;
updateAvailability(id: number, dto: UpdateParkingAvailabilityDto): Promise<ParkingLot>;
getParkingLotHistory(id: number, limit?: number): Promise<ParkingUpdate[]>;
}

View File

@@ -0,0 +1,207 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingController = void 0;
const common_1 = require("@nestjs/common");
const swagger_1 = require("@nestjs/swagger");
const throttler_1 = require("@nestjs/throttler");
const parking_service_1 = require("./parking.service");
const find_nearby_parking_dto_1 = require("./dto/find-nearby-parking.dto");
const update_availability_dto_1 = require("./dto/update-availability.dto");
const parking_lot_entity_1 = require("./entities/parking-lot.entity");
const parking_update_entity_1 = require("./entities/parking-update.entity");
let ParkingController = class ParkingController {
constructor(parkingService) {
this.parkingService = parkingService;
}
async findNearbyParking(dto) {
return this.parkingService.findNearbyParking(dto);
}
async getAllParkingLots() {
return this.parkingService.getAllParkingLots();
}
async getPopularParkingLots(limit) {
return this.parkingService.getPopularParkingLots(limit);
}
async getParkingLotById(id) {
return this.parkingService.findById(id);
}
async updateAvailability(id, dto) {
return this.parkingService.updateAvailability(id, dto);
}
async getParkingLotHistory(id, limit) {
return this.parkingService.getParkingLotHistory(id, limit);
}
};
exports.ParkingController = ParkingController;
__decorate([
(0, common_1.Post)('nearby'),
(0, swagger_1.ApiOperation)({
summary: 'Find nearby parking lots',
description: 'Search for parking lots within a specified radius of the given coordinates'
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully found nearby parking lots',
type: parking_lot_entity_1.ParkingLot,
isArray: true,
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.BAD_REQUEST,
description: 'Invalid coordinates or parameters',
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.INTERNAL_SERVER_ERROR,
description: 'Failed to search for parking lots',
}),
__param(0, (0, common_1.Body)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [find_nearby_parking_dto_1.FindNearbyParkingDto]),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "findNearbyParking", null);
__decorate([
(0, common_1.Get)(),
(0, swagger_1.ApiOperation)({
summary: 'Get all parking lots',
description: 'Retrieve all active parking lots in the system'
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully retrieved parking lots',
type: parking_lot_entity_1.ParkingLot,
isArray: true,
}),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "getAllParkingLots", null);
__decorate([
(0, common_1.Get)('popular'),
(0, swagger_1.ApiOperation)({
summary: 'Get popular parking lots',
description: 'Retrieve the most frequently visited parking lots'
}),
(0, swagger_1.ApiQuery)({
name: 'limit',
required: false,
description: 'Maximum number of results',
example: 10
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully retrieved popular parking lots',
type: parking_lot_entity_1.ParkingLot,
isArray: true,
}),
__param(0, (0, common_1.Query)('limit')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number]),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "getPopularParkingLots", null);
__decorate([
(0, common_1.Get)(':id'),
(0, swagger_1.ApiOperation)({
summary: 'Get parking lot details',
description: 'Retrieve detailed information about a specific parking lot'
}),
(0, swagger_1.ApiParam)({
name: 'id',
description: 'Parking lot ID',
example: 1
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully retrieved parking lot details',
type: parking_lot_entity_1.ParkingLot,
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.NOT_FOUND,
description: 'Parking lot not found',
}),
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number]),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "getParkingLotById", null);
__decorate([
(0, common_1.Put)(':id/availability'),
(0, swagger_1.ApiBearerAuth)(),
(0, swagger_1.ApiOperation)({
summary: 'Update parking availability',
description: 'Update the number of available slots for a parking lot'
}),
(0, swagger_1.ApiParam)({
name: 'id',
description: 'Parking lot ID',
example: 1
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully updated parking availability',
type: parking_lot_entity_1.ParkingLot,
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.NOT_FOUND,
description: 'Parking lot not found',
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.BAD_REQUEST,
description: 'Invalid availability data',
}),
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
__param(1, (0, common_1.Body)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, update_availability_dto_1.UpdateParkingAvailabilityDto]),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "updateAvailability", null);
__decorate([
(0, common_1.Get)(':id/history'),
(0, swagger_1.ApiOperation)({
summary: 'Get parking lot update history',
description: 'Retrieve the update history for a specific parking lot'
}),
(0, swagger_1.ApiParam)({
name: 'id',
description: 'Parking lot ID',
example: 1
}),
(0, swagger_1.ApiQuery)({
name: 'limit',
required: false,
description: 'Maximum number of history records',
example: 100
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.OK,
description: 'Successfully retrieved parking lot history',
type: parking_update_entity_1.ParkingUpdate,
isArray: true,
}),
(0, swagger_1.ApiResponse)({
status: common_1.HttpStatus.NOT_FOUND,
description: 'Parking lot not found',
}),
__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
__param(1, (0, common_1.Query)('limit')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number, Number]),
__metadata("design:returntype", Promise)
], ParkingController.prototype, "getParkingLotHistory", null);
exports.ParkingController = ParkingController = __decorate([
(0, swagger_1.ApiTags)('Parking'),
(0, common_1.Controller)('parking'),
(0, common_1.UseGuards)(throttler_1.ThrottlerGuard),
__metadata("design:paramtypes", [parking_service_1.ParkingService])
], ParkingController);
//# sourceMappingURL=parking.controller.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking.controller.js","sourceRoot":"","sources":["../../../src/modules/parking/parking.controller.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,2 @@
export declare class ParkingModule {
}

View File

@@ -0,0 +1,34 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingModule = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const parking_controller_1 = require("./parking.controller");
const parking_service_1 = require("./parking.service");
const parking_lot_entity_1 = require("./entities/parking-lot.entity");
const parking_history_entity_1 = require("./entities/parking-history.entity");
const parking_update_entity_1 = require("./entities/parking-update.entity");
let ParkingModule = class ParkingModule {
};
exports.ParkingModule = ParkingModule;
exports.ParkingModule = ParkingModule = __decorate([
(0, common_1.Module)({
imports: [
typeorm_1.TypeOrmModule.forFeature([
parking_lot_entity_1.ParkingLot,
parking_history_entity_1.ParkingHistory,
parking_update_entity_1.ParkingUpdate,
]),
],
controllers: [parking_controller_1.ParkingController],
providers: [parking_service_1.ParkingService],
exports: [parking_service_1.ParkingService],
})
], ParkingModule);
//# sourceMappingURL=parking.module.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking.module.js","sourceRoot":"","sources":["../../../src/modules/parking/parking.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6CAAgD;AAChD,6DAAyD;AACzD,uDAAmD;AACnD,sEAA2D;AAC3D,8EAAmE;AACnE,4EAAiE;AAc1D,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IAZzB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC;gBACvB,+BAAU;gBACV,uCAAc;gBACd,qCAAa;aACd,CAAC;SACH;QACD,WAAW,EAAE,CAAC,sCAAiB,CAAC;QAChC,SAAS,EAAE,CAAC,gCAAc,CAAC;QAC3B,OAAO,EAAE,CAAC,gCAAc,CAAC;KAC1B,CAAC;GACW,aAAa,CAAG"}

View File

@@ -0,0 +1,24 @@
import { Repository } from 'typeorm';
import { ParkingLot } from './entities/parking-lot.entity';
import { ParkingUpdate } from './entities/parking-update.entity';
import { FindNearbyParkingDto } from './dto/find-nearby-parking.dto';
import { UpdateParkingAvailabilityDto } from './dto/update-availability.dto';
export declare class ParkingService {
private readonly parkingRepository;
private readonly updateRepository;
private readonly logger;
constructor(parkingRepository: Repository<ParkingLot>, updateRepository: Repository<ParkingUpdate>);
findNearbyParking(dto: FindNearbyParkingDto): Promise<{
parkingLots: ParkingLot[];
userLocation: {
lat: number;
lng: number;
};
searchRadius: number;
}>;
findById(id: number): Promise<ParkingLot>;
updateAvailability(id: number, dto: UpdateParkingAvailabilityDto): Promise<ParkingLot>;
getAllParkingLots(): Promise<ParkingLot[]>;
getParkingLotHistory(id: number, limit?: number): Promise<ParkingUpdate[]>;
getPopularParkingLots(limit?: number): Promise<ParkingLot[]>;
}

View File

@@ -0,0 +1,148 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var ParkingService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParkingService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const parking_lot_entity_1 = require("./entities/parking-lot.entity");
const parking_update_entity_1 = require("./entities/parking-update.entity");
let ParkingService = ParkingService_1 = class ParkingService {
constructor(parkingRepository, updateRepository) {
this.parkingRepository = parkingRepository;
this.updateRepository = updateRepository;
this.logger = new common_1.Logger(ParkingService_1.name);
}
async findNearbyParking(dto) {
try {
this.logger.debug(`Finding parking near ${dto.lat}, ${dto.lng} within ${dto.radius}m`);
let query = this.parkingRepository
.createQueryBuilder('lot')
.select([
'lot.*',
'ST_Distance(lot.location::geography, ST_Point(:lng, :lat)::geography) as distance'
])
.where('ST_DWithin(lot.location::geography, ST_Point(:lng, :lat)::geography, :radius)', {
lng: dto.lng,
lat: dto.lat,
radius: dto.radius,
})
.andWhere('lot.isActive = :isActive', { isActive: true });
if (dto.priceRange && dto.priceRange.length === 2) {
query = query.andWhere('lot.hourlyRate BETWEEN :minPrice AND :maxPrice', { minPrice: dto.priceRange[0], maxPrice: dto.priceRange[1] });
}
if (dto.amenities && dto.amenities.length > 0) {
dto.amenities.forEach((amenity, index) => {
query = query.andWhere(`lot.amenities ? :amenity${index}`, { [`amenity${index}`]: amenity });
});
}
if (dto.availabilityFilter) {
switch (dto.availabilityFilter) {
case 'available':
query = query.andWhere('(lot.availableSlots::float / lot.totalSlots::float) > 0.2');
break;
case 'limited':
query = query.andWhere('(lot.availableSlots::float / lot.totalSlots::float) BETWEEN 0.05 AND 0.2');
break;
case 'full':
query = query.andWhere('(lot.availableSlots::float / lot.totalSlots::float) < 0.05');
break;
}
}
const results = await query
.orderBy('distance', 'ASC')
.limit(dto.maxResults)
.getRawMany();
const parkingLots = results.map((result) => {
const { distance, ...lotData } = result;
const lot = this.parkingRepository.create(lotData);
lot.distance = parseFloat(distance);
return lot;
});
return {
parkingLots,
userLocation: { lat: dto.lat, lng: dto.lng },
searchRadius: dto.radius,
};
}
catch (error) {
this.logger.error('Failed to find nearby parking', error);
throw new common_1.InternalServerErrorException('Failed to find nearby parking');
}
}
async findById(id) {
const lot = await this.parkingRepository.findOne({
where: { id },
relations: ['updates'],
});
if (!lot) {
throw new common_1.NotFoundException(`Parking lot with ID ${id} not found`);
}
return lot;
}
async updateAvailability(id, dto) {
const lot = await this.findById(id);
const update = this.updateRepository.create({
parkingLotId: id,
availableSlots: dto.availableSlots,
source: dto.source,
confidence: dto.confidence,
metadata: dto.metadata,
});
await this.updateRepository.save(update);
lot.availableSlots = dto.availableSlots;
lot.updatedAt = new Date();
return this.parkingRepository.save(lot);
}
async getAllParkingLots() {
return this.parkingRepository.find({
where: { isActive: true },
order: { name: 'ASC' },
});
}
async getParkingLotHistory(id, limit = 100) {
return this.updateRepository.find({
where: { parkingLotId: id },
order: { timestamp: 'DESC' },
take: limit,
});
}
async getPopularParkingLots(limit = 10) {
const results = await this.parkingRepository
.createQueryBuilder('lot')
.leftJoin('lot.history', 'history')
.select(['lot.*', 'COUNT(history.id) as visit_count'])
.where('lot.isActive = :isActive', { isActive: true })
.groupBy('lot.id')
.orderBy('visit_count', 'DESC')
.limit(limit)
.getRawMany();
return results.map((result) => {
const { visit_count, ...lotData } = result;
const lot = this.parkingRepository.create(lotData);
lot.visitCount = parseInt(visit_count) || 0;
return lot;
});
}
};
exports.ParkingService = ParkingService;
exports.ParkingService = ParkingService = ParkingService_1 = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, typeorm_1.InjectRepository)(parking_lot_entity_1.ParkingLot)),
__param(1, (0, typeorm_1.InjectRepository)(parking_update_entity_1.ParkingUpdate)),
__metadata("design:paramtypes", [typeorm_2.Repository,
typeorm_2.Repository])
], ParkingService);
//# sourceMappingURL=parking.service.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parking.service.js","sourceRoot":"","sources":["../../../src/modules/parking/parking.service.ts"],"names":[],"mappings":"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"}