feat: implement billing, usage tracking, and administrative geocoding features in API with infrastructure updates
This commit is contained in:
Vendored
+17
-2
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.AppModule = void 0;
|
exports.AppModule = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
|
const core_1 = require("@nestjs/core");
|
||||||
const config_1 = require("@nestjs/config");
|
const config_1 = require("@nestjs/config");
|
||||||
const typeorm_1 = require("@nestjs/typeorm");
|
const typeorm_1 = require("@nestjs/typeorm");
|
||||||
const schedule_1 = require("@nestjs/schedule");
|
const schedule_1 = require("@nestjs/schedule");
|
||||||
@@ -16,6 +17,10 @@ const maps_module_1 = require("./maps/maps.module");
|
|||||||
const geocoding_module_1 = require("./geocoding/geocoding.module");
|
const geocoding_module_1 = require("./geocoding/geocoding.module");
|
||||||
const auth_module_1 = require("./auth/auth.module");
|
const auth_module_1 = require("./auth/auth.module");
|
||||||
const throttler_1 = require("@nestjs/throttler");
|
const throttler_1 = require("@nestjs/throttler");
|
||||||
|
const usage_module_1 = require("./usage/usage.module");
|
||||||
|
const billing_module_1 = require("./billing/billing.module");
|
||||||
|
const mail_module_1 = require("./common/mail.module");
|
||||||
|
const usage_interceptor_1 = require("./usage/usage.interceptor");
|
||||||
let AppModule = class AppModule {
|
let AppModule = class AppModule {
|
||||||
};
|
};
|
||||||
exports.AppModule = AppModule;
|
exports.AppModule = AppModule;
|
||||||
@@ -33,17 +38,27 @@ exports.AppModule = AppModule = __decorate([
|
|||||||
type: 'postgres',
|
type: 'postgres',
|
||||||
url: config.get('DATABASE_URL'),
|
url: config.get('DATABASE_URL'),
|
||||||
autoLoadEntities: true,
|
autoLoadEntities: true,
|
||||||
synchronize: true,
|
synchronize: false,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
throttler_1.ThrottlerModule.forRoot([{
|
throttler_1.ThrottlerModule.forRoot([{
|
||||||
ttl: 60,
|
ttl: 60000,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
}]),
|
}]),
|
||||||
auth_module_1.AuthModule,
|
auth_module_1.AuthModule,
|
||||||
telemetry_module_1.TelemetryModule,
|
telemetry_module_1.TelemetryModule,
|
||||||
maps_module_1.MapsModule,
|
maps_module_1.MapsModule,
|
||||||
geocoding_module_1.GeocodingModule,
|
geocoding_module_1.GeocodingModule,
|
||||||
|
usage_module_1.UsageModule,
|
||||||
|
billing_module_1.BillingModule,
|
||||||
|
mail_module_1.MailModule,
|
||||||
|
],
|
||||||
|
controllers: [],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: core_1.APP_INTERCEPTOR,
|
||||||
|
useClass: usage_interceptor_1.UsageInterceptor,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
], AppModule);
|
], AppModule);
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,2CAA6D;AAC7D,6CAAgD;AAChD,+CAAkD;AAClD,mEAA+D;AAC/D,oDAAgD;AAChD,mEAA+D;AAC/D,oDAAgD;AAChD,iDAAoD;AA4B7C,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IA1BrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,qBAAY,CAAC,OAAO,CAAC;gBACnB,QAAQ,EAAE,IAAI;aACf,CAAC;YACF,yBAAc,CAAC,OAAO,EAAE;YACxB,uBAAa,CAAC,YAAY,CAAC;gBACzB,OAAO,EAAE,CAAC,qBAAY,CAAC;gBACvB,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,CAAC,MAAqB,EAAE,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,UAAU;oBAChB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;oBAC/B,gBAAgB,EAAE,IAAI;oBACtB,WAAW,EAAE,IAAI;iBAClB,CAAC;aACH,CAAC;YACF,2BAAe,CAAC,OAAO,CAAC,CAAC;oBACvB,GAAG,EAAE,EAAE;oBACP,KAAK,EAAE,EAAE;iBACV,CAAC,CAAC;YACH,wBAAU;YACV,kCAAe;YACf,wBAAU;YACV,kCAAe;SAChB;KACF,CAAC;GACW,SAAS,CAAG"}
|
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,uCAA0D;AAC1D,2CAA6D;AAC7D,6CAAgD;AAChD,+CAAkD;AAClD,mEAA+D;AAC/D,oDAAgD;AAChD,mEAA+D;AAC/D,oDAAgD;AAChD,iDAAoD;AACpD,uDAAmD;AACnD,6DAAyD;AACzD,sDAAkD;AAClD,iEAA6D;AAsCtD,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IApCrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,qBAAY,CAAC,OAAO,CAAC;gBACnB,QAAQ,EAAE,IAAI;aACf,CAAC;YACF,yBAAc,CAAC,OAAO,EAAE;YACxB,uBAAa,CAAC,YAAY,CAAC;gBACzB,OAAO,EAAE,CAAC,qBAAY,CAAC;gBACvB,MAAM,EAAE,CAAC,sBAAa,CAAC;gBACvB,UAAU,EAAE,CAAC,MAAqB,EAAE,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,UAAU;oBAChB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;oBAC/B,gBAAgB,EAAE,IAAI;oBACtB,WAAW,EAAE,KAAK;iBACnB,CAAC;aACH,CAAC;YACF,2BAAe,CAAC,OAAO,CAAC,CAAC;oBACvB,GAAG,EAAE,KAAK;oBACV,KAAK,EAAE,EAAE;iBACV,CAAC,CAAC;YACH,wBAAU;YACV,kCAAe;YACf,wBAAU;YACV,kCAAe;YACf,0BAAW;YACX,8BAAa;YACb,wBAAU;SACX;QACD,WAAW,EAAE,EAAE;QACf,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,oCAAgB;aAC3B;SACF;KACF,CAAC;GACW,SAAS,CAAG"}
|
||||||
Vendored
+8
-4
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
};
|
};
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.AuthModule = void 0;
|
exports.AuthModule = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -17,6 +18,9 @@ const tenant_entity_1 = require("./entities/tenant.entity");
|
|||||||
const api_key_entity_1 = require("./entities/api-key.entity");
|
const api_key_entity_1 = require("./entities/api-key.entity");
|
||||||
const redis_module_1 = require("../common/redis.module");
|
const redis_module_1 = require("../common/redis.module");
|
||||||
const config_1 = require("@nestjs/config");
|
const config_1 = require("@nestjs/config");
|
||||||
|
const tenant_controller_1 = require("./tenant.controller");
|
||||||
|
const firebase_admin_service_1 = require("./firebase-admin.service");
|
||||||
|
const firebase_auth_guard_1 = require("./guards/firebase-auth.guard");
|
||||||
let AuthModule = class AuthModule {
|
let AuthModule = class AuthModule {
|
||||||
authService;
|
authService;
|
||||||
configService;
|
configService;
|
||||||
@@ -40,10 +44,10 @@ exports.AuthModule = AuthModule = __decorate([
|
|||||||
typeorm_1.TypeOrmModule.forFeature([tenant_entity_1.Tenant, api_key_entity_1.ApiKey]),
|
typeorm_1.TypeOrmModule.forFeature([tenant_entity_1.Tenant, api_key_entity_1.ApiKey]),
|
||||||
redis_module_1.RedisModule,
|
redis_module_1.RedisModule,
|
||||||
],
|
],
|
||||||
providers: [auth_service_1.AuthService],
|
controllers: [tenant_controller_1.TenantController],
|
||||||
exports: [auth_service_1.AuthService],
|
providers: [auth_service_1.AuthService, firebase_admin_service_1.FirebaseAdminService, firebase_auth_guard_1.FirebaseAuthGuard],
|
||||||
|
exports: [auth_service_1.AuthService, firebase_admin_service_1.FirebaseAdminService, firebase_auth_guard_1.FirebaseAuthGuard],
|
||||||
}),
|
}),
|
||||||
__metadata("design:paramtypes", [auth_service_1.AuthService,
|
__metadata("design:paramtypes", [auth_service_1.AuthService, typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
config_1.ConfigService])
|
|
||||||
], AuthModule);
|
], AuthModule);
|
||||||
//# sourceMappingURL=auth.module.js.map
|
//# sourceMappingURL=auth.module.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA8D;AAC9D,6CAAgD;AAChD,iDAA6C;AAC7C,4DAAkD;AAClD,8DAAmD;AACnD,yDAAqD;AACrD,2CAA+C;AAWxC,IAAM,UAAU,GAAhB,MAAM,UAAU;IAEF;IACA;IAFnB,YACmB,WAAwB,EACxB,aAA4B;QAD5B,gBAAW,GAAX,WAAW,CAAa;QACxB,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAMJ,KAAK,CAAC,YAAY;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,aAAa,CAAC,CAAC;QACjE,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;YACzF,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF,CAAA;AAjBY,gCAAU;qBAAV,UAAU;IATtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC,CAAC,sBAAM,EAAE,uBAAM,CAAC,CAAC;YAC1C,0BAAW;SACZ;QACD,SAAS,EAAE,CAAC,0BAAW,CAAC;QACxB,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;qCAGgC,0BAAW;QACT,sBAAa;GAHpC,UAAU,CAiBtB"}
|
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAA8D;AAC9D,6CAAgD;AAChD,iDAA6C;AAC7C,4DAAkD;AAClD,8DAAmD;AACnD,yDAAqD;AACrD,2CAA+C;AAC/C,2DAAuD;AACvD,qEAAgE;AAChE,sEAAiE;AAY1D,IAAM,UAAU,GAAhB,MAAM,UAAU;IAEF;IACA;IAFnB,YACmB,WAAwB,EACxB,aAA4B;QAD5B,gBAAW,GAAX,WAAW,CAAa;QACxB,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAMJ,KAAK,CAAC,YAAY;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,aAAa,CAAC,CAAC;QACjE,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,CAAC,CAAC;YACzF,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF,CAAA;AAjBY,gCAAU;qBAAV,UAAU;IAVtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC,CAAC,sBAAM,EAAE,uBAAM,CAAC,CAAC;YAC1C,0BAAW;SACZ;QACD,WAAW,EAAE,CAAC,oCAAgB,CAAC;QAC/B,SAAS,EAAE,CAAC,0BAAW,EAAE,6CAAoB,EAAE,uCAAiB,CAAC;QACjE,OAAO,EAAE,CAAC,0BAAW,EAAE,6CAAoB,EAAE,uCAAiB,CAAC;KAChE,CAAC;qCAGgC,0BAAW,sBACT,sBAAa,oBAAb,sBAAa;GAHpC,UAAU,CAiBtB"}
|
||||||
Vendored
+4
@@ -17,4 +17,8 @@ export declare class AuthService {
|
|||||||
private isDomainAllowed;
|
private isDomainAllowed;
|
||||||
hashSecret(secret: string): string;
|
hashSecret(secret: string): string;
|
||||||
seedDefaultKey(name: string, email: string, keyString: string): Promise<void>;
|
seedDefaultKey(name: string, email: string, keyString: string): Promise<void>;
|
||||||
|
getApiKeys(tenantId: string): Promise<ApiKey[]>;
|
||||||
|
createApiKey(tenantId: string, name: string, rateLimit?: number, allowedOrigins?: string[]): Promise<ApiKey>;
|
||||||
|
getDefaultTenant(): Promise<Tenant>;
|
||||||
|
findOrCreateByFirebaseUid(uid: string, email: string, name: string, photoUrl?: string): Promise<Tenant>;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+70
-5
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
return function (target, key) { decorator(target, key, paramIndex); }
|
||||||
};
|
};
|
||||||
var AuthService_1;
|
var AuthService_1;
|
||||||
|
var _a, _b;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.AuthService = void 0;
|
exports.AuthService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -49,7 +50,7 @@ let AuthService = AuthService_1 = class AuthService {
|
|||||||
const result = {
|
const result = {
|
||||||
tenant: apiKey.tenant,
|
tenant: apiKey.tenant,
|
||||||
apiKey: apiKey,
|
apiKey: apiKey,
|
||||||
rateLimit: apiKey.rateLimit || 100,
|
rateLimit: apiKey.rateLimit || tenant_entity_1.RATE_LIMITS[apiKey.tenant.plan] || 100,
|
||||||
};
|
};
|
||||||
await this.redisService.set(cacheKey, result, 3600);
|
await this.redisService.set(cacheKey, result, 3600);
|
||||||
this.apiKeyRepository.update(apiKey.id, { lastUsedAt: new Date() }).catch(err => this.logger.error(`Failed to update lastUsedAt for API key ${apiKey.id}: ${err.message}`));
|
this.apiKeyRepository.update(apiKey.id, { lastUsedAt: new Date() }).catch(err => this.logger.error(`Failed to update lastUsedAt for API key ${apiKey.id}: ${err.message}`));
|
||||||
@@ -87,7 +88,8 @@ let AuthService = AuthService_1 = class AuthService {
|
|||||||
tenant = await this.tenantRepository.save({
|
tenant = await this.tenantRepository.save({
|
||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
isActive: true
|
isActive: true,
|
||||||
|
plan: tenant_entity_1.TenantPlan.ENTERPRISE,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const existingKey = await this.apiKeyRepository.findOne({ where: { key: keyString } });
|
const existingKey = await this.apiKeyRepository.findOne({ where: { key: keyString } });
|
||||||
@@ -102,14 +104,77 @@ let AuthService = AuthService_1 = class AuthService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async getApiKeys(tenantId) {
|
||||||
|
return this.apiKeyRepository.find({
|
||||||
|
where: { tenantId },
|
||||||
|
order: { createdAt: 'DESC' }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async createApiKey(tenantId, name, rateLimit, allowedOrigins) {
|
||||||
|
const existingKeysCount = await this.apiKeyRepository.count({ where: { tenantId } });
|
||||||
|
if (existingKeysCount >= 1) {
|
||||||
|
throw new common_1.ConflictException('Limit reached: Only 1 API key allowed per developer currently.');
|
||||||
|
}
|
||||||
|
const key = `in_${(0, crypto_1.createHash)('md5').update(Math.random().toString()).digest('hex').substring(0, 24)}`;
|
||||||
|
const apiKey = this.apiKeyRepository.create({
|
||||||
|
key,
|
||||||
|
secretHash: this.hashSecret(key),
|
||||||
|
name,
|
||||||
|
tenantId,
|
||||||
|
rateLimit: rateLimit || 100,
|
||||||
|
allowedOrigins: allowedOrigins || [],
|
||||||
|
isActive: true
|
||||||
|
});
|
||||||
|
return this.apiKeyRepository.save(apiKey);
|
||||||
|
}
|
||||||
|
async getDefaultTenant() {
|
||||||
|
const tenant = await this.tenantRepository.findOne({ where: {} });
|
||||||
|
if (!tenant)
|
||||||
|
throw new common_1.NotFoundException('No tenants found in system');
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
async findOrCreateByFirebaseUid(uid, email, name, photoUrl) {
|
||||||
|
let tenant = await this.tenantRepository.findOne({ where: { firebaseUid: uid } });
|
||||||
|
if (!tenant) {
|
||||||
|
tenant = await this.tenantRepository.findOne({ where: { email } });
|
||||||
|
if (tenant) {
|
||||||
|
this.logger.log(`Linking existing tenant ${email} to Firebase UID: ${uid}`);
|
||||||
|
tenant.firebaseUid = uid;
|
||||||
|
if (photoUrl)
|
||||||
|
tenant.photoUrl = photoUrl;
|
||||||
|
tenant = await this.tenantRepository.save(tenant);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.logger.log(`Creating new tenant for Firebase user: ${email} (${uid})`);
|
||||||
|
const isAdmin = email === 'hamzaaleghwairyeen@gmail.com' || email === 'hamzadoctor@gmail.com' || email === 'hamzaayedpython@gmail.com';
|
||||||
|
tenant = await this.tenantRepository.save({
|
||||||
|
firebaseUid: uid,
|
||||||
|
email,
|
||||||
|
name,
|
||||||
|
photoUrl,
|
||||||
|
plan: isAdmin ? tenant_entity_1.TenantPlan.ENTERPRISE : tenant_entity_1.TenantPlan.FREE,
|
||||||
|
isActive: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const isAdmin = email === 'hamzaaleghwairyeen@gmail.com' || email === 'hamzadoctor@gmail.com' || email === 'hamzaayedpython@gmail.com';
|
||||||
|
if (isAdmin && tenant.plan !== tenant_entity_1.TenantPlan.ENTERPRISE) {
|
||||||
|
tenant.plan = tenant_entity_1.TenantPlan.ENTERPRISE;
|
||||||
|
await this.tenantRepository.save(tenant);
|
||||||
|
}
|
||||||
|
if (tenant.photoUrl !== photoUrl || tenant.name !== name) {
|
||||||
|
await this.tenantRepository.update(tenant.id, { photoUrl, name });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
exports.AuthService = AuthService;
|
exports.AuthService = AuthService;
|
||||||
exports.AuthService = AuthService = AuthService_1 = __decorate([
|
exports.AuthService = AuthService = AuthService_1 = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__param(0, (0, typeorm_1.InjectRepository)(api_key_entity_1.ApiKey)),
|
__param(0, (0, typeorm_1.InjectRepository)(api_key_entity_1.ApiKey)),
|
||||||
__param(1, (0, typeorm_1.InjectRepository)(tenant_entity_1.Tenant)),
|
__param(1, (0, typeorm_1.InjectRepository)(tenant_entity_1.Tenant)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, redis_service_1.RedisService])
|
||||||
typeorm_2.Repository,
|
|
||||||
redis_service_1.RedisService])
|
|
||||||
], AuthService);
|
], AuthService);
|
||||||
//# sourceMappingURL=auth.service.js.map
|
//# sourceMappingURL=auth.service.js.map
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
|
|||||||
|
export declare class CreateKeyDto {
|
||||||
|
name: string;
|
||||||
|
rateLimit?: number;
|
||||||
|
allowedOrigins?: string[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"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.CreateKeyDto = void 0;
|
||||||
|
const class_validator_1 = require("class-validator");
|
||||||
|
class CreateKeyDto {
|
||||||
|
name;
|
||||||
|
rateLimit;
|
||||||
|
allowedOrigins;
|
||||||
|
}
|
||||||
|
exports.CreateKeyDto = CreateKeyDto;
|
||||||
|
__decorate([
|
||||||
|
(0, class_validator_1.IsString)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], CreateKeyDto.prototype, "name", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, class_validator_1.IsOptional)(),
|
||||||
|
(0, class_validator_1.IsNumber)(),
|
||||||
|
__metadata("design:type", Number)
|
||||||
|
], CreateKeyDto.prototype, "rateLimit", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, class_validator_1.IsOptional)(),
|
||||||
|
(0, class_validator_1.IsArray)(),
|
||||||
|
(0, class_validator_1.IsString)({ each: true }),
|
||||||
|
__metadata("design:type", Array)
|
||||||
|
], CreateKeyDto.prototype, "allowedOrigins", void 0);
|
||||||
|
//# sourceMappingURL=create-key.dto.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"create-key.dto.js","sourceRoot":"","sources":["../../../../src/auth/dto/management/create-key.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA0E;AAE1E,MAAa,YAAY;IAEvB,IAAI,CAAS;IAIb,SAAS,CAAU;IAKnB,cAAc,CAAY;CAC3B;AAZD,oCAYC;AAVC;IADC,IAAA,0BAAQ,GAAE;;0CACE;AAIb;IAFC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;+CACQ;AAKnB;IAHC,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;oDACC"}
|
||||||
+11
-1
@@ -1,14 +1,24 @@
|
|||||||
import { ApiKey } from './api-key.entity';
|
import { ApiKey } from './api-key.entity';
|
||||||
export declare enum TenantPlan {
|
export declare enum TenantPlan {
|
||||||
FREE = "FREE",
|
FREE = "FREE",
|
||||||
PREMIUM = "PREMIUM",
|
STARTER = "STARTER",
|
||||||
|
PRO = "PRO",
|
||||||
ENTERPRISE = "ENTERPRISE"
|
ENTERPRISE = "ENTERPRISE"
|
||||||
}
|
}
|
||||||
|
export declare enum TenantRole {
|
||||||
|
USER = "USER",
|
||||||
|
ADMIN = "ADMIN"
|
||||||
|
}
|
||||||
|
export declare const QUOTA_LIMITS: Record<TenantPlan, number>;
|
||||||
|
export declare const RATE_LIMITS: Record<TenantPlan, number>;
|
||||||
export declare class Tenant {
|
export declare class Tenant {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
plan: TenantPlan;
|
plan: TenantPlan;
|
||||||
|
firebaseUid: string;
|
||||||
|
role: TenantRole;
|
||||||
|
photoUrl: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
|||||||
+39
-2
@@ -9,20 +9,41 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Tenant = exports.TenantPlan = void 0;
|
exports.Tenant = exports.RATE_LIMITS = exports.QUOTA_LIMITS = exports.TenantRole = exports.TenantPlan = void 0;
|
||||||
const typeorm_1 = require("typeorm");
|
const typeorm_1 = require("typeorm");
|
||||||
const api_key_entity_1 = require("./api-key.entity");
|
const api_key_entity_1 = require("./api-key.entity");
|
||||||
var TenantPlan;
|
var TenantPlan;
|
||||||
(function (TenantPlan) {
|
(function (TenantPlan) {
|
||||||
TenantPlan["FREE"] = "FREE";
|
TenantPlan["FREE"] = "FREE";
|
||||||
TenantPlan["PREMIUM"] = "PREMIUM";
|
TenantPlan["STARTER"] = "STARTER";
|
||||||
|
TenantPlan["PRO"] = "PRO";
|
||||||
TenantPlan["ENTERPRISE"] = "ENTERPRISE";
|
TenantPlan["ENTERPRISE"] = "ENTERPRISE";
|
||||||
})(TenantPlan || (exports.TenantPlan = TenantPlan = {}));
|
})(TenantPlan || (exports.TenantPlan = TenantPlan = {}));
|
||||||
|
var TenantRole;
|
||||||
|
(function (TenantRole) {
|
||||||
|
TenantRole["USER"] = "USER";
|
||||||
|
TenantRole["ADMIN"] = "ADMIN";
|
||||||
|
})(TenantRole || (exports.TenantRole = TenantRole = {}));
|
||||||
|
exports.QUOTA_LIMITS = {
|
||||||
|
[TenantPlan.FREE]: 8000,
|
||||||
|
[TenantPlan.STARTER]: 25000,
|
||||||
|
[TenantPlan.PRO]: 100000,
|
||||||
|
[TenantPlan.ENTERPRISE]: 500000,
|
||||||
|
};
|
||||||
|
exports.RATE_LIMITS = {
|
||||||
|
[TenantPlan.FREE]: 5,
|
||||||
|
[TenantPlan.STARTER]: 100,
|
||||||
|
[TenantPlan.PRO]: 500,
|
||||||
|
[TenantPlan.ENTERPRISE]: 50000,
|
||||||
|
};
|
||||||
let Tenant = class Tenant {
|
let Tenant = class Tenant {
|
||||||
id;
|
id;
|
||||||
name;
|
name;
|
||||||
email;
|
email;
|
||||||
plan;
|
plan;
|
||||||
|
firebaseUid;
|
||||||
|
role;
|
||||||
|
photoUrl;
|
||||||
isActive;
|
isActive;
|
||||||
createdAt;
|
createdAt;
|
||||||
updatedAt;
|
updatedAt;
|
||||||
@@ -49,6 +70,22 @@ __decorate([
|
|||||||
}),
|
}),
|
||||||
__metadata("design:type", String)
|
__metadata("design:type", String)
|
||||||
], Tenant.prototype, "plan", void 0);
|
], Tenant.prototype, "plan", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ nullable: true, unique: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Tenant.prototype, "firebaseUid", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: TenantRole,
|
||||||
|
default: TenantRole.USER,
|
||||||
|
}),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Tenant.prototype, "role", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Tenant.prototype, "photoUrl", void 0);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, typeorm_1.Column)({ default: true }),
|
(0, typeorm_1.Column)({ default: true }),
|
||||||
__metadata("design:type", Boolean)
|
__metadata("design:type", Boolean)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"tenant.entity.js","sourceRoot":"","sources":["../../../src/auth/entities/tenant.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAgH;AAChH,qDAA0C;AAE1C,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,iCAAmB,CAAA;IACnB,uCAAyB,CAAA;AAC3B,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB;AAGM,IAAM,MAAM,GAAZ,MAAM,MAAM;IAEjB,EAAE,CAAS;IAGX,IAAI,CAAS;IAGb,KAAK,CAAS;IAOd,IAAI,CAAa;IAGjB,QAAQ,CAAU;IAGlB,SAAS,CAAO;IAGhB,SAAS,CAAO;IAGhB,OAAO,CAAW;CACnB,CAAA;AA5BY,wBAAM;AAEjB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;kCACpB;AAGX;IADC,IAAA,gBAAM,GAAE;;oCACI;AAGb;IADC,IAAA,gBAAM,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;qCACX;AAOd;IALC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU,CAAC,IAAI;KACzB,CAAC;;oCACe;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;wCACR;AAGlB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;yCAAC;AAGhB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;yCAAC;AAGhB;IADC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,uBAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;;uCACjC;iBA3BP,MAAM;IADlB,IAAA,gBAAM,EAAC,SAAS,CAAC;GACL,MAAM,CA4BlB"}
|
{"version":3,"file":"tenant.entity.js","sourceRoot":"","sources":["../../../src/auth/entities/tenant.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAgH;AAChH,qDAA0C;AAE1C,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,iCAAmB,CAAA;IACnB,yBAAW,CAAA;IACX,uCAAyB,CAAA;AAC3B,CAAC,EALW,UAAU,0BAAV,UAAU,QAKrB;AAED,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,6BAAe,CAAA;AACjB,CAAC,EAHW,UAAU,0BAAV,UAAU,QAGrB;AAEY,QAAA,YAAY,GAA+B;IACtD,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI;IACvB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK;IAC3B,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM;IACxB,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM;CAChC,CAAC;AAEW,QAAA,WAAW,GAA+B;IACrD,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;IACzB,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,GAAG;IACrB,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,KAAK;CAC/B,CAAC;AAGK,IAAM,MAAM,GAAZ,MAAM,MAAM;IAEjB,EAAE,CAAS;IAGX,IAAI,CAAS;IAGb,KAAK,CAAS;IAOd,IAAI,CAAa;IAGjB,WAAW,CAAS;IAOpB,IAAI,CAAa;IAGjB,QAAQ,CAAS;IAGjB,QAAQ,CAAU;IAGlB,SAAS,CAAO;IAGhB,SAAS,CAAO;IAGhB,OAAO,CAAW;CACnB,CAAA;AAzCY,wBAAM;AAEjB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;kCACpB;AAGX;IADC,IAAA,gBAAM,GAAE;;oCACI;AAGb;IADC,IAAA,gBAAM,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;qCACX;AAOd;IALC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU,CAAC,IAAI;KACzB,CAAC;;oCACe;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;2CACrB;AAOpB;IALC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU,CAAC,IAAI;KACzB,CAAC;;oCACe;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wCACV;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;wCACR;AAGlB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;yCAAC;AAGhB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;yCAAC;AAGhB;IADC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,uBAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;;uCACjC;iBAxCP,MAAM;IADlB,IAAA,gBAAM,EAAC,SAAS,CAAC;GACL,MAAM,CAyClB"}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
import { OnModuleInit } from '@nestjs/common';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import * as admin from 'firebase-admin';
|
||||||
|
export declare class FirebaseAdminService implements OnModuleInit {
|
||||||
|
private configService;
|
||||||
|
private readonly logger;
|
||||||
|
private firebaseApp;
|
||||||
|
constructor(configService: ConfigService);
|
||||||
|
onModuleInit(): void;
|
||||||
|
verifyIdToken(token: string): Promise<admin.auth.DecodedIdToken>;
|
||||||
|
}
|
||||||
+99
@@ -0,0 +1,99 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
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 __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
|
};
|
||||||
|
var FirebaseAdminService_1;
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.FirebaseAdminService = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const config_1 = require("@nestjs/config");
|
||||||
|
const admin = __importStar(require("firebase-admin"));
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
let FirebaseAdminService = FirebaseAdminService_1 = class FirebaseAdminService {
|
||||||
|
configService;
|
||||||
|
logger = new common_1.Logger(FirebaseAdminService_1.name);
|
||||||
|
firebaseApp;
|
||||||
|
constructor(configService) {
|
||||||
|
this.configService = configService;
|
||||||
|
}
|
||||||
|
onModuleInit() {
|
||||||
|
const keyPath = this.configService.get('FIREBASE_SERVICE_ACCOUNT_PATH');
|
||||||
|
if (!keyPath) {
|
||||||
|
this.logger.error('FIREBASE_SERVICE_ACCOUNT_PATH is not defined in environment variables');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const absolutePath = path.isAbsolute(keyPath)
|
||||||
|
? keyPath
|
||||||
|
: path.resolve(process.cwd(), keyPath);
|
||||||
|
if (!fs.existsSync(absolutePath)) {
|
||||||
|
this.logger.error(`Firebase service account key not found at: ${absolutePath}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const serviceAccount = JSON.parse(fs.readFileSync(absolutePath, 'utf8'));
|
||||||
|
this.firebaseApp = admin.initializeApp({
|
||||||
|
credential: admin.credential.cert(serviceAccount),
|
||||||
|
});
|
||||||
|
this.logger.log('✅ Firebase Admin SDK initialized successfully');
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Failed to initialize Firebase Admin SDK: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async verifyIdToken(token) {
|
||||||
|
try {
|
||||||
|
return await admin.auth().verifyIdToken(token);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Token verification failed: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.FirebaseAdminService = FirebaseAdminService;
|
||||||
|
exports.FirebaseAdminService = FirebaseAdminService = FirebaseAdminService_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
|
], FirebaseAdminService);
|
||||||
|
//# sourceMappingURL=firebase-admin.service.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"firebase-admin.service.js","sourceRoot":"","sources":["../../src/auth/firebase-admin.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAkE;AAClE,2CAA+C;AAC/C,sDAAwC;AACxC,uCAAyB;AACzB,2CAA6B;AAGtB,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IAIX;IAHH,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;IACxD,WAAW,CAAgB;IAEnC,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,YAAY;QACV,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,+BAA+B,CAAC,CAAC;QAEhF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YAC3F,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YAEH,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC3C,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;YAEzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,YAAY,EAAE,CAAC,CAAC;gBAChF,OAAO;YACT,CAAC;YAED,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YAEzE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,aAAa,CAAC;gBACrC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC;aAClD,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAa;QAC/B,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAA;AA7CY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;yDAKwB,sBAAa,oBAAb,sBAAa;GAJrC,oBAAoB,CA6ChC"}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||||
|
import { FirebaseAdminService } from '../firebase-admin.service';
|
||||||
|
import { AuthService } from '../auth.service';
|
||||||
|
export declare class FirebaseAuthGuard implements CanActivate {
|
||||||
|
private firebaseAdminService;
|
||||||
|
private authService;
|
||||||
|
private readonly logger;
|
||||||
|
constructor(firebaseAdminService: FirebaseAdminService, authService: AuthService);
|
||||||
|
canActivate(context: ExecutionContext): Promise<boolean>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
"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 FirebaseAuthGuard_1;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.FirebaseAuthGuard = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const firebase_admin_service_1 = require("../firebase-admin.service");
|
||||||
|
const auth_service_1 = require("../auth.service");
|
||||||
|
let FirebaseAuthGuard = FirebaseAuthGuard_1 = class FirebaseAuthGuard {
|
||||||
|
firebaseAdminService;
|
||||||
|
authService;
|
||||||
|
logger = new common_1.Logger(FirebaseAuthGuard_1.name);
|
||||||
|
constructor(firebaseAdminService, authService) {
|
||||||
|
this.firebaseAdminService = firebaseAdminService;
|
||||||
|
this.authService = authService;
|
||||||
|
}
|
||||||
|
async canActivate(context) {
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
const authHeader = request.headers.authorization;
|
||||||
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||||
|
throw new common_1.UnauthorizedException('Missing or invalid Authorization header');
|
||||||
|
}
|
||||||
|
const token = authHeader.split('Bearer ')[1];
|
||||||
|
try {
|
||||||
|
const decodedToken = await this.firebaseAdminService.verifyIdToken(token);
|
||||||
|
const tenant = await this.authService.findOrCreateByFirebaseUid(decodedToken.uid, decodedToken.email || '', decodedToken.name || decodedToken.email?.split('@')[0] || 'Unknown User', decodedToken.picture);
|
||||||
|
if (!tenant.isActive) {
|
||||||
|
throw new common_1.UnauthorizedException('Tenant account is disabled');
|
||||||
|
}
|
||||||
|
request['tenant'] = tenant;
|
||||||
|
request['user'] = decodedToken;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Firebase Auth failed: ${error.message}`);
|
||||||
|
throw new common_1.UnauthorizedException(error.message || 'Authentication failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.FirebaseAuthGuard = FirebaseAuthGuard;
|
||||||
|
exports.FirebaseAuthGuard = FirebaseAuthGuard = FirebaseAuthGuard_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__metadata("design:paramtypes", [firebase_admin_service_1.FirebaseAdminService,
|
||||||
|
auth_service_1.AuthService])
|
||||||
|
], FirebaseAuthGuard);
|
||||||
|
//# sourceMappingURL=firebase-auth.guard.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"firebase-auth.guard.js","sourceRoot":"","sources":["../../../src/auth/guards/firebase-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAMwB;AACxB,sEAAiE;AACjE,kDAA8C;AAGvC,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAIlB;IACA;IAJO,MAAM,GAAG,IAAI,eAAM,CAAC,mBAAiB,CAAC,IAAI,CAAC,CAAC;IAE7D,YACU,oBAA0C,EAC1C,WAAwB;QADxB,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,gBAAW,GAAX,WAAW,CAAa;IAC/B,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QAEjD,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,8BAAqB,CAAC,yCAAyC,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAG1E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAC7D,YAAY,CAAC,GAAG,EAChB,YAAY,CAAC,KAAK,IAAI,EAAE,EACxB,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,cAAc,EACxE,YAAY,CAAC,OAAO,CACrB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrB,MAAM,IAAI,8BAAqB,CAAC,4BAA4B,CAAC,CAAC;YAChE,CAAC;YAGD,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;YAE/B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,MAAM,IAAI,8BAAqB,CAAC,KAAK,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;CACF,CAAA;AA5CY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;qCAKqB,6CAAoB;QAC7B,0BAAW;GALvB,iBAAiB,CA4C7B"}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import { AuthService } from './auth.service';
|
||||||
|
import { CreateKeyDto } from './dto/management/create-key.dto';
|
||||||
|
export declare class TenantController {
|
||||||
|
private readonly authService;
|
||||||
|
constructor(authService: AuthService);
|
||||||
|
createKey(req: any, dto: CreateKeyDto): Promise<import("./entities/api-key.entity").ApiKey>;
|
||||||
|
getKeys(req: any): Promise<import("./entities/api-key.entity").ApiKey[]>;
|
||||||
|
getMe(req: any): Promise<any>;
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
"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.TenantController = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const auth_service_1 = require("./auth.service");
|
||||||
|
const create_key_dto_1 = require("./dto/management/create-key.dto");
|
||||||
|
const swagger_1 = require("@nestjs/swagger");
|
||||||
|
const firebase_auth_guard_1 = require("./guards/firebase-auth.guard");
|
||||||
|
let TenantController = class TenantController {
|
||||||
|
authService;
|
||||||
|
constructor(authService) {
|
||||||
|
this.authService = authService;
|
||||||
|
}
|
||||||
|
async createKey(req, dto) {
|
||||||
|
if (req.user && req.user.email_verified === false) {
|
||||||
|
throw new common_1.ForbiddenException('You must verify your email address before creating an API key.');
|
||||||
|
}
|
||||||
|
const tenantId = req.tenant.id;
|
||||||
|
return this.authService.createApiKey(tenantId, dto.name, dto.rateLimit, dto.allowedOrigins);
|
||||||
|
}
|
||||||
|
async getKeys(req) {
|
||||||
|
const tenantId = req.tenant.id;
|
||||||
|
return this.authService.getApiKeys(tenantId);
|
||||||
|
}
|
||||||
|
async getMe(req) {
|
||||||
|
return req.tenant;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.TenantController = TenantController;
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Post)('keys'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Create a new API key' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__param(1, (0, common_1.Body)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, create_key_dto_1.CreateKeyDto]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], TenantController.prototype, "createKey", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Get)('keys'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Get all API keys for the authenticated tenant' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], TenantController.prototype, "getKeys", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Get)('me'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Get current authenticated tenant info' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], TenantController.prototype, "getMe", null);
|
||||||
|
exports.TenantController = TenantController = __decorate([
|
||||||
|
(0, swagger_1.ApiTags)('auth'),
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Controller)('auth/management'),
|
||||||
|
__metadata("design:paramtypes", [auth_service_1.AuthService])
|
||||||
|
], TenantController);
|
||||||
|
//# sourceMappingURL=tenant.controller.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"tenant.controller.js","sourceRoot":"","sources":["../../src/auth/tenant.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwG;AACxG,iDAA6C;AAC7C,oEAA+D;AAC/D,6CAAuE;AACvE,sEAAiE;AAM1D,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IACE;IAA7B,YAA6B,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAInD,AAAN,KAAK,CAAC,SAAS,CACN,GAAQ,EACP,GAAiB;QAEzB,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;YAClD,MAAM,IAAI,2BAAkB,CAAC,gEAAgE,CAAC,CAAC;QACjG,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAClC,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,SAAS,EACb,GAAG,CAAC,cAAc,CACnB,CAAC;IACJ,CAAC;IAIK,AAAN,KAAK,CAAC,OAAO,CAAQ,GAAQ;QAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAIK,AAAN,KAAK,CAAC,KAAK,CAAQ,GAAQ;QACzB,OAAO,GAAG,CAAC,MAAM,CAAC;IACpB,CAAC;CACF,CAAA;AAlCY,4CAAgB;AAKrB;IAFL,IAAA,aAAI,EAAC,MAAM,CAAC;IACZ,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAE/C,WAAA,IAAA,YAAG,GAAE,CAAA;IACL,WAAA,IAAA,aAAI,GAAE,CAAA;;6CAAM,6BAAY;;iDAa1B;AAIK;IAFL,IAAA,YAAG,EAAC,MAAM,CAAC;IACX,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,+CAA+C,EAAE,CAAC;IAC5D,WAAA,IAAA,YAAG,GAAE,CAAA;;;;+CAGnB;AAIK;IAFL,IAAA,YAAG,EAAC,IAAI,CAAC;IACT,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC;IACtD,WAAA,IAAA,YAAG,GAAE,CAAA;;;;6CAEjB;2BAjCU,gBAAgB;IAJ5B,IAAA,iBAAO,EAAC,MAAM,CAAC;IACf,IAAA,uBAAa,GAAE;IACf,IAAA,kBAAS,EAAC,uCAAiB,CAAC;IAC5B,IAAA,mBAAU,EAAC,iBAAiB,CAAC;qCAEc,0BAAW;GAD1C,gBAAgB,CAkC5B"}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
import { BillingService } from './billing.service';
|
||||||
|
import { PayMobProvider } from './providers/paymob.provider';
|
||||||
|
import { BinanceProvider } from './providers/binance.provider';
|
||||||
|
import { PaymentProvider } from './entities/transaction.entity';
|
||||||
|
export declare class BillingController {
|
||||||
|
private billingService;
|
||||||
|
private paymobProvider;
|
||||||
|
private binanceProvider;
|
||||||
|
private readonly logger;
|
||||||
|
constructor(billingService: BillingService, paymobProvider: PayMobProvider, binanceProvider: BinanceProvider);
|
||||||
|
getSubscription(req: any): Promise<import("./entities/subscription.entity").Subscription>;
|
||||||
|
checkout(req: any, body: {
|
||||||
|
plan: string;
|
||||||
|
provider: PaymentProvider;
|
||||||
|
}): Promise<{
|
||||||
|
checkoutUrl: any;
|
||||||
|
orderId: string;
|
||||||
|
prepayId: any;
|
||||||
|
} | {
|
||||||
|
checkoutUrl: string;
|
||||||
|
orderId: string;
|
||||||
|
}>;
|
||||||
|
handlePaymobCallback(query: any, req: any): Promise<string>;
|
||||||
|
handlePaymobWebhook(body: any, hmac: string): Promise<{
|
||||||
|
status: string;
|
||||||
|
message: string;
|
||||||
|
} | {
|
||||||
|
status: string;
|
||||||
|
message?: undefined;
|
||||||
|
}>;
|
||||||
|
handleBinanceWebhook(body: any, req: any): Promise<{
|
||||||
|
returnCode: string;
|
||||||
|
returnMessage: any;
|
||||||
|
}>;
|
||||||
|
getInvoices(req: any): Promise<import("./entities/transaction.entity").Transaction[]>;
|
||||||
|
}
|
||||||
+259
@@ -0,0 +1,259 @@
|
|||||||
|
"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 BillingController_1;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BillingController = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const billing_service_1 = require("./billing.service");
|
||||||
|
const paymob_provider_1 = require("./providers/paymob.provider");
|
||||||
|
const binance_provider_1 = require("./providers/binance.provider");
|
||||||
|
const firebase_auth_guard_1 = require("../auth/guards/firebase-auth.guard");
|
||||||
|
const swagger_1 = require("@nestjs/swagger");
|
||||||
|
const transaction_entity_1 = require("./entities/transaction.entity");
|
||||||
|
let BillingController = BillingController_1 = class BillingController {
|
||||||
|
billingService;
|
||||||
|
paymobProvider;
|
||||||
|
binanceProvider;
|
||||||
|
logger = new common_1.Logger(BillingController_1.name);
|
||||||
|
constructor(billingService, paymobProvider, binanceProvider) {
|
||||||
|
this.billingService = billingService;
|
||||||
|
this.paymobProvider = paymobProvider;
|
||||||
|
this.binanceProvider = binanceProvider;
|
||||||
|
}
|
||||||
|
async getSubscription(req) {
|
||||||
|
return this.billingService.getSubscription(req.tenant.id);
|
||||||
|
}
|
||||||
|
async checkout(req, body) {
|
||||||
|
const tenantId = req.tenant.id;
|
||||||
|
const plan = body.plan;
|
||||||
|
const pricing = {
|
||||||
|
'STARTER': 29,
|
||||||
|
'PRO': 89,
|
||||||
|
};
|
||||||
|
const amount = pricing[plan] || 0;
|
||||||
|
if (amount === 0 && plan !== 'FREE') {
|
||||||
|
throw new common_1.BadRequestException('Invalid plan or price not configured');
|
||||||
|
}
|
||||||
|
if (body.provider === transaction_entity_1.PaymentProvider.PAYMOB) {
|
||||||
|
const { paymentKey, orderId } = await this.paymobProvider.createPaymentKey(tenantId, amount, plan);
|
||||||
|
const iframeId = this.billingService.getIframeId();
|
||||||
|
const checkoutUrl = `https://accept.paymob.com/api/acceptance/iframes/${iframeId}?payment_token=${paymentKey}`;
|
||||||
|
return { checkoutUrl, orderId };
|
||||||
|
}
|
||||||
|
if (body.provider === transaction_entity_1.PaymentProvider.BINANCE) {
|
||||||
|
return this.binanceProvider.createOrder(tenantId, amount, plan);
|
||||||
|
}
|
||||||
|
throw new common_1.BadRequestException('Invalid payment provider');
|
||||||
|
}
|
||||||
|
async handlePaymobCallback(query, req) {
|
||||||
|
this.logger.log(`🔄 PayMob Redirect Callback: ID ${query.id}, Success: ${query.success}`);
|
||||||
|
if (query.success === 'true' && query.id) {
|
||||||
|
try {
|
||||||
|
const txDetails = await this.paymobProvider.getTransactionDetails(query.id);
|
||||||
|
if (txDetails && txDetails.success === true) {
|
||||||
|
const extraDesc = txDetails.order?.shipping_data?.extra_description || "";
|
||||||
|
const [tenantId, plan] = extraDesc.split('|');
|
||||||
|
if (tenantId) {
|
||||||
|
await this.billingService.processSuccessfulPayment(query.id.toString(), transaction_entity_1.PaymentProvider.PAYMOB, txDetails.amount_cents / 100, { tenantId, plan: plan || 'PRO' });
|
||||||
|
this.logger.log(`🚀 Immediate Activation triggered via Callback for Tenant ${tenantId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.logger.error(`Failed during immediate activation fallback: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const targetUrl = `https://map-dashboard.intaleqapp.com/dashboard.html#billing?payment_status=${query.success === 'true' ? 'success' : 'failed'}&id=${query.id}`;
|
||||||
|
return `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ar" dir="rtl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Intaleq Maps | تمت العملية بنجاح</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700;900&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body { font-family: 'Cairo', sans-serif; background: #050505; color: white; overflow: hidden; }
|
||||||
|
.pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
|
||||||
|
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .7; transform: scale(0.95); } }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="flex items-center justify-center h-screen">
|
||||||
|
<div class="text-center space-y-8 max-w-md p-10 bg-white shadow-2xl rounded-[3rem] border border-white/10 relative overflow-hidden">
|
||||||
|
<!-- Animated Background Glow -->
|
||||||
|
<div class="absolute -top-20 -left-20 w-40 h-40 bg-blue-600/20 blur-[80px] rounded-full"></div>
|
||||||
|
<div class="absolute -bottom-20 -right-20 w-40 h-40 bg-emerald-600/20 blur-[80px] rounded-full"></div>
|
||||||
|
|
||||||
|
<div class="relative z-10">
|
||||||
|
<div class="w-24 h-24 bg-emerald-500 rounded-full mx-auto flex items-center justify-center shadow-[0_0_50px_rgba(16,185,129,0.4)] pulse mb-8">
|
||||||
|
<svg class="w-12 h-12 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M5 13l4 4L19 7"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 class="text-3xl font-black text-slate-900 mb-4">شكراً لك، حمزة!</h1>
|
||||||
|
<p class="text-slate-500 font-bold mb-8">تم تفعيل خطة <span class="text-blue-600">PRO</span> بنجاح. يتم الآن توجيهك إلى لوحة التحكم...</p>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-center gap-2">
|
||||||
|
<div class="w-2 h-2 bg-blue-600 rounded-full animate-bounce"></div>
|
||||||
|
<div class="w-2 h-2 bg-blue-600 rounded-full animate-bounce [animation-delay:-0.15s]"></div>
|
||||||
|
<div class="w-2 h-2 bg-blue-600 rounded-full animate-bounce [animation-delay:-0.3s]"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "${targetUrl}";
|
||||||
|
}, 2500);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
async handlePaymobWebhook(body, hmac) {
|
||||||
|
this.logger.log(`📥 PayMob Webhook Received: Transaction ID ${body.obj?.id}`);
|
||||||
|
if (!this.paymobProvider.verifyHmac(body.obj, hmac)) {
|
||||||
|
this.logger.error('❌ PayMob HMAC Verification Failed');
|
||||||
|
throw new common_1.BadRequestException('Invalid signature');
|
||||||
|
}
|
||||||
|
if (body.obj.success === true) {
|
||||||
|
const extraDesc = body.obj.order?.shipping_data?.extra_description || "";
|
||||||
|
const [tenantId, plan] = extraDesc.split('|');
|
||||||
|
if (!tenantId) {
|
||||||
|
this.logger.error(`❌ PayMob Webhook failed: No tenantId in metadata. Raw: ${extraDesc}`);
|
||||||
|
return { status: 'error', message: 'No tenantId found' };
|
||||||
|
}
|
||||||
|
await this.billingService.processSuccessfulPayment(body.obj.id.toString(), transaction_entity_1.PaymentProvider.PAYMOB, body.obj.amount_cents / 100, {
|
||||||
|
tenantId,
|
||||||
|
plan: plan || 'PRO'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { status: 'success' };
|
||||||
|
}
|
||||||
|
async handleBinanceWebhook(body, req) {
|
||||||
|
const timestamp = req.headers['binancepay-timestamp'];
|
||||||
|
const nonce = req.headers['binancepay-nonce'];
|
||||||
|
const signature = req.headers['binancepay-signature'];
|
||||||
|
this.logger.log(`📥 Binance Webhook Received: Transaction ID ${body.bizId || 'UNKNOWN'}`);
|
||||||
|
if (!timestamp || !nonce || !signature) {
|
||||||
|
this.logger.error('❌ Binance Webhook: Missing required headers');
|
||||||
|
throw new common_1.BadRequestException('Missing headers');
|
||||||
|
}
|
||||||
|
if (!this.binanceProvider.verifySignature(timestamp, nonce, signature, body)) {
|
||||||
|
this.logger.error('❌ Binance Signature Verification Failed');
|
||||||
|
throw new common_1.BadRequestException('Invalid signature');
|
||||||
|
}
|
||||||
|
if (body.bizStatus === 'PAY_SUCCESS') {
|
||||||
|
try {
|
||||||
|
let dataObj = {};
|
||||||
|
if (body.data) {
|
||||||
|
dataObj = JSON.parse(body.data);
|
||||||
|
}
|
||||||
|
let tenantId = '';
|
||||||
|
let plan = 'PRO';
|
||||||
|
if (dataObj.passThroughInfo) {
|
||||||
|
const passThrough = JSON.parse(dataObj.passThroughInfo);
|
||||||
|
tenantId = passThrough.tenantId;
|
||||||
|
plan = passThrough.plan;
|
||||||
|
}
|
||||||
|
if (!tenantId) {
|
||||||
|
this.logger.error(`❌ Binance Webhook failed: No tenantId found. Body: ${JSON.stringify(body)}`);
|
||||||
|
return { returnCode: 'FAIL', returnMessage: 'No tenantId found' };
|
||||||
|
}
|
||||||
|
const externalTxId = dataObj.merchantTradeNo || body.bizId?.toString();
|
||||||
|
await this.billingService.processSuccessfulPayment(externalTxId, transaction_entity_1.PaymentProvider.BINANCE, 0, { tenantId, plan });
|
||||||
|
this.logger.log(`✅ Binance Payment Processed Successfully for Tenant ${tenantId}`);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.logger.error(`❌ Failed to process Binance payment: ${err.message}`);
|
||||||
|
return { returnCode: 'FAIL', returnMessage: err.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
returnCode: 'SUCCESS',
|
||||||
|
returnMessage: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async getInvoices(req) {
|
||||||
|
return this.billingService.getTransactionHistory(req.tenant.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.BillingController = BillingController;
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Get)('subscription'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Get current subscription details' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "getSubscription", null);
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Post)('checkout'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Initialize a checkout session' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__param(1, (0, common_1.Body)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "checkout", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Get)('callback/paymob'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'PayMob Redirection Handler' }),
|
||||||
|
__param(0, (0, common_1.Query)()),
|
||||||
|
__param(1, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "handlePaymobCallback", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Post)('webhooks/paymob'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'PayMob Payment Webhook' }),
|
||||||
|
__param(0, (0, common_1.Body)()),
|
||||||
|
__param(1, (0, common_1.Query)('hmac')),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, String]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "handlePaymobWebhook", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Post)('webhooks/binance'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Binance Payment Webhook' }),
|
||||||
|
__param(0, (0, common_1.Body)()),
|
||||||
|
__param(1, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "handleBinanceWebhook", null);
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Get)('invoices'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Get payment history' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], BillingController.prototype, "getInvoices", null);
|
||||||
|
exports.BillingController = BillingController = BillingController_1 = __decorate([
|
||||||
|
(0, swagger_1.ApiTags)('billing'),
|
||||||
|
(0, common_1.Controller)('billing'),
|
||||||
|
__metadata("design:paramtypes", [billing_service_1.BillingService,
|
||||||
|
paymob_provider_1.PayMobProvider,
|
||||||
|
binance_provider_1.BinanceProvider])
|
||||||
|
], BillingController);
|
||||||
|
//# sourceMappingURL=billing.controller.js.map
|
||||||
File diff suppressed because one or more lines are too long
+2
@@ -0,0 +1,2 @@
|
|||||||
|
export declare class BillingModule {
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
"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.BillingModule = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const typeorm_1 = require("@nestjs/typeorm");
|
||||||
|
const subscription_entity_1 = require("./entities/subscription.entity");
|
||||||
|
const transaction_entity_1 = require("./entities/transaction.entity");
|
||||||
|
const billing_service_1 = require("./billing.service");
|
||||||
|
const billing_controller_1 = require("./billing.controller");
|
||||||
|
const paymob_provider_1 = require("./providers/paymob.provider");
|
||||||
|
const binance_provider_1 = require("./providers/binance.provider");
|
||||||
|
const tenant_entity_1 = require("../auth/entities/tenant.entity");
|
||||||
|
let BillingModule = class BillingModule {
|
||||||
|
};
|
||||||
|
exports.BillingModule = BillingModule;
|
||||||
|
exports.BillingModule = BillingModule = __decorate([
|
||||||
|
(0, common_1.Module)({
|
||||||
|
imports: [
|
||||||
|
typeorm_1.TypeOrmModule.forFeature([subscription_entity_1.Subscription, transaction_entity_1.Transaction, tenant_entity_1.Tenant]),
|
||||||
|
],
|
||||||
|
providers: [billing_service_1.BillingService, paymob_provider_1.PayMobProvider, binance_provider_1.BinanceProvider],
|
||||||
|
controllers: [billing_controller_1.BillingController],
|
||||||
|
exports: [billing_service_1.BillingService],
|
||||||
|
})
|
||||||
|
], BillingModule);
|
||||||
|
//# sourceMappingURL=billing.module.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"billing.module.js","sourceRoot":"","sources":["../../src/billing/billing.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6CAAgD;AAChD,wEAA8D;AAC9D,sEAA4D;AAC5D,uDAAmD;AACnD,6DAAyD;AACzD,iEAA6D;AAC7D,mEAA+D;AAC/D,kEAAwD;AAUjD,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IARzB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC,CAAC,kCAAY,EAAE,gCAAW,EAAE,sBAAM,CAAC,CAAC;SAC9D;QACD,SAAS,EAAE,CAAC,gCAAc,EAAE,gCAAc,EAAE,kCAAe,CAAC;QAC5D,WAAW,EAAE,CAAC,sCAAiB,CAAC;QAChC,OAAO,EAAE,CAAC,gCAAc,CAAC;KAC1B,CAAC;GACW,aAAa,CAAG"}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { Subscription } from './entities/subscription.entity';
|
||||||
|
import { Transaction, PaymentProvider } from './entities/transaction.entity';
|
||||||
|
import { Tenant } from '../auth/entities/tenant.entity';
|
||||||
|
import { MailService } from '../common/mail.service';
|
||||||
|
export declare class BillingService {
|
||||||
|
private subscriptionRepository;
|
||||||
|
private transactionRepository;
|
||||||
|
private tenantRepository;
|
||||||
|
private configService;
|
||||||
|
private mailService;
|
||||||
|
private readonly logger;
|
||||||
|
constructor(subscriptionRepository: Repository<Subscription>, transactionRepository: Repository<Transaction>, tenantRepository: Repository<Tenant>, configService: ConfigService, mailService: MailService);
|
||||||
|
getIframeId(): string;
|
||||||
|
getSubscription(tenantId: string): Promise<Subscription>;
|
||||||
|
processSuccessfulPayment(externalTxId: string, provider: PaymentProvider, amount: number, metadata: any): Promise<void>;
|
||||||
|
private upgradeTenantPlan;
|
||||||
|
getTransactionHistory(tenantId: string): Promise<Transaction[]>;
|
||||||
|
}
|
||||||
+131
@@ -0,0 +1,131 @@
|
|||||||
|
"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 BillingService_1;
|
||||||
|
var _a, _b, _c, _d;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BillingService = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const config_1 = require("@nestjs/config");
|
||||||
|
const typeorm_1 = require("@nestjs/typeorm");
|
||||||
|
const typeorm_2 = require("typeorm");
|
||||||
|
const subscription_entity_1 = require("./entities/subscription.entity");
|
||||||
|
const transaction_entity_1 = require("./entities/transaction.entity");
|
||||||
|
const tenant_entity_1 = require("../auth/entities/tenant.entity");
|
||||||
|
const mail_service_1 = require("../common/mail.service");
|
||||||
|
let BillingService = BillingService_1 = class BillingService {
|
||||||
|
subscriptionRepository;
|
||||||
|
transactionRepository;
|
||||||
|
tenantRepository;
|
||||||
|
configService;
|
||||||
|
mailService;
|
||||||
|
logger = new common_1.Logger(BillingService_1.name);
|
||||||
|
constructor(subscriptionRepository, transactionRepository, tenantRepository, configService, mailService) {
|
||||||
|
this.subscriptionRepository = subscriptionRepository;
|
||||||
|
this.transactionRepository = transactionRepository;
|
||||||
|
this.tenantRepository = tenantRepository;
|
||||||
|
this.configService = configService;
|
||||||
|
this.mailService = mailService;
|
||||||
|
}
|
||||||
|
getIframeId() {
|
||||||
|
return this.configService.get('PAYMOB_IFRAME_ID', '837992');
|
||||||
|
}
|
||||||
|
async getSubscription(tenantId) {
|
||||||
|
let sub = await this.subscriptionRepository.findOne({ where: { tenantId } });
|
||||||
|
if (!sub) {
|
||||||
|
sub = await this.subscriptionRepository.save({
|
||||||
|
tenantId,
|
||||||
|
plan: 'FREE',
|
||||||
|
monthlyRequestLimit: 5000,
|
||||||
|
status: subscription_entity_1.SubscriptionStatus.ACTIVE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
async processSuccessfulPayment(externalTxId, provider, amount, metadata) {
|
||||||
|
let txn = await this.transactionRepository.findOne({ where: { externalTransactionId: externalTxId } });
|
||||||
|
if (txn && txn.status === transaction_entity_1.PaymentStatus.SUCCESS) {
|
||||||
|
this.logger.warn(`Transaction ${externalTxId} already processed.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!txn) {
|
||||||
|
const tenantId = metadata.tenantId;
|
||||||
|
if (!tenantId)
|
||||||
|
throw new common_1.BadRequestException('No tenantId found in payment metadata');
|
||||||
|
txn = await this.transactionRepository.save({
|
||||||
|
tenantId,
|
||||||
|
externalTransactionId: externalTxId,
|
||||||
|
amount,
|
||||||
|
provider,
|
||||||
|
status: transaction_entity_1.PaymentStatus.SUCCESS,
|
||||||
|
metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
txn.status = transaction_entity_1.PaymentStatus.SUCCESS;
|
||||||
|
txn.metadata = { ...txn.metadata, ...metadata };
|
||||||
|
await this.transactionRepository.save(txn);
|
||||||
|
}
|
||||||
|
const tenantId = txn.tenantId;
|
||||||
|
const plan = metadata.plan || 'PRO';
|
||||||
|
await this.upgradeTenantPlan(tenantId, plan);
|
||||||
|
try {
|
||||||
|
const tenant = await this.tenantRepository.findOne({ where: { id: tenantId } });
|
||||||
|
if (tenant && tenant.email) {
|
||||||
|
await this.mailService.sendInvoiceEmail(tenant.email, {
|
||||||
|
tenantName: tenant.name,
|
||||||
|
plan: plan,
|
||||||
|
amount: `${amount} EGP`,
|
||||||
|
transactionId: externalTxId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.logger.error(`Failed to send invoice email for tx ${externalTxId}: ${err.message}`);
|
||||||
|
}
|
||||||
|
this.logger.log(`✅ Tenant ${tenantId} upgraded to ${plan} after payment ${externalTxId}`);
|
||||||
|
}
|
||||||
|
async upgradeTenantPlan(tenantId, plan) {
|
||||||
|
await this.tenantRepository.update(tenantId, { plan });
|
||||||
|
const limits = {
|
||||||
|
[tenant_entity_1.TenantPlan.FREE]: 5000,
|
||||||
|
[tenant_entity_1.TenantPlan.STARTER]: 25000,
|
||||||
|
[tenant_entity_1.TenantPlan.PRO]: 100000,
|
||||||
|
[tenant_entity_1.TenantPlan.ENTERPRISE]: 500000,
|
||||||
|
};
|
||||||
|
const sub = await this.getSubscription(tenantId);
|
||||||
|
sub.plan = plan;
|
||||||
|
sub.monthlyRequestLimit = limits[plan] || 8000;
|
||||||
|
sub.status = subscription_entity_1.SubscriptionStatus.ACTIVE;
|
||||||
|
sub.currentPeriodStart = new Date();
|
||||||
|
const nextMonth = new Date();
|
||||||
|
nextMonth.setMonth(nextMonth.getMonth() + 1);
|
||||||
|
sub.currentPeriodEnd = nextMonth;
|
||||||
|
await this.subscriptionRepository.save(sub);
|
||||||
|
}
|
||||||
|
async getTransactionHistory(tenantId) {
|
||||||
|
return this.transactionRepository.find({
|
||||||
|
where: { tenantId },
|
||||||
|
order: { createdAt: 'DESC' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.BillingService = BillingService;
|
||||||
|
exports.BillingService = BillingService = BillingService_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__param(0, (0, typeorm_1.InjectRepository)(subscription_entity_1.Subscription)),
|
||||||
|
__param(1, (0, typeorm_1.InjectRepository)(transaction_entity_1.Transaction)),
|
||||||
|
__param(2, (0, typeorm_1.InjectRepository)(tenant_entity_1.Tenant)),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, typeof (_c = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _c : Object, typeof (_d = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _d : Object, mail_service_1.MailService])
|
||||||
|
], BillingService);
|
||||||
|
//# sourceMappingURL=billing.service.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"billing.service.js","sourceRoot":"","sources":["../../src/billing/billing.service.ts"],"names":[],"mappings":"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"}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
export declare enum SubscriptionStatus {
|
||||||
|
ACTIVE = "ACTIVE",
|
||||||
|
PAST_DUE = "PAST_DUE",
|
||||||
|
CANCELED = "CANCELED",
|
||||||
|
TRIALING = "TRIALING"
|
||||||
|
}
|
||||||
|
export declare class Subscription {
|
||||||
|
id: string;
|
||||||
|
tenantId: string;
|
||||||
|
plan: string;
|
||||||
|
status: SubscriptionStatus;
|
||||||
|
monthlyRequestLimit: number;
|
||||||
|
currentPeriodStart: Date;
|
||||||
|
currentPeriodEnd: Date;
|
||||||
|
canceledAt: Date;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
"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.Subscription = exports.SubscriptionStatus = void 0;
|
||||||
|
const typeorm_1 = require("typeorm");
|
||||||
|
var SubscriptionStatus;
|
||||||
|
(function (SubscriptionStatus) {
|
||||||
|
SubscriptionStatus["ACTIVE"] = "ACTIVE";
|
||||||
|
SubscriptionStatus["PAST_DUE"] = "PAST_DUE";
|
||||||
|
SubscriptionStatus["CANCELED"] = "CANCELED";
|
||||||
|
SubscriptionStatus["TRIALING"] = "TRIALING";
|
||||||
|
})(SubscriptionStatus || (exports.SubscriptionStatus = SubscriptionStatus = {}));
|
||||||
|
let Subscription = class Subscription {
|
||||||
|
id;
|
||||||
|
tenantId;
|
||||||
|
plan;
|
||||||
|
status;
|
||||||
|
monthlyRequestLimit;
|
||||||
|
currentPeriodStart;
|
||||||
|
currentPeriodEnd;
|
||||||
|
canceledAt;
|
||||||
|
createdAt;
|
||||||
|
updatedAt;
|
||||||
|
};
|
||||||
|
exports.Subscription = Subscription;
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Subscription.prototype, "id", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
(0, typeorm_1.Column)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Subscription.prototype, "tenantId", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ default: 'FREE' }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Subscription.prototype, "plan", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: SubscriptionStatus,
|
||||||
|
default: SubscriptionStatus.ACTIVE,
|
||||||
|
}),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Subscription.prototype, "status", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'int', default: 8000 }),
|
||||||
|
__metadata("design:type", Number)
|
||||||
|
], Subscription.prototype, "monthlyRequestLimit", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'timestamp', nullable: true }),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Subscription.prototype, "currentPeriodStart", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'timestamp', nullable: true }),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Subscription.prototype, "currentPeriodEnd", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'timestamp', nullable: true }),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Subscription.prototype, "canceledAt", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.CreateDateColumn)(),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Subscription.prototype, "createdAt", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.UpdateDateColumn)(),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Subscription.prototype, "updatedAt", void 0);
|
||||||
|
exports.Subscription = Subscription = __decorate([
|
||||||
|
(0, typeorm_1.Entity)('subscriptions')
|
||||||
|
], Subscription);
|
||||||
|
//# sourceMappingURL=subscription.entity.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"subscription.entity.js","sourceRoot":"","sources":["../../../src/billing/entities/subscription.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAQiB;AAGjB,IAAY,kBAKX;AALD,WAAY,kBAAkB;IAC5B,uCAAiB,CAAA;IACjB,2CAAqB,CAAA;IACrB,2CAAqB,CAAA;IACrB,2CAAqB,CAAA;AACvB,CAAC,EALW,kBAAkB,kCAAlB,kBAAkB,QAK7B;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEvB,EAAE,CAAS;IAIX,QAAQ,CAAS;IAGjB,IAAI,CAAS;IAOb,MAAM,CAAqB;IAG3B,mBAAmB,CAAS;IAG5B,kBAAkB,CAAO;IAGzB,gBAAgB,CAAO;IAGvB,UAAU,CAAO;IAGjB,SAAS,CAAO;IAGhB,SAAS,CAAO;CACjB,CAAA;AAnCY,oCAAY;AAEvB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;wCACpB;AAIX;IAFC,IAAA,eAAK,GAAE;IACP,IAAA,gBAAM,GAAE;;8CACQ;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;;0CACf;AAOb;IALC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,kBAAkB,CAAC,MAAM;KACnC,CAAC;;4CACyB;AAG3B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;yDACX;AAG5B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BAC1B,IAAI;wDAAC;AAGzB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BAC5B,IAAI;sDAAC;AAGvB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BAClC,IAAI;gDAAC;AAGjB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;+CAAC;AAGhB;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;+CAAC;uBAlCL,YAAY;IADxB,IAAA,gBAAM,EAAC,eAAe,CAAC;GACX,YAAY,CAmCxB"}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
export declare enum PaymentStatus {
|
||||||
|
PENDING = "PENDING",
|
||||||
|
SUCCESS = "SUCCESS",
|
||||||
|
FAILED = "FAILED",
|
||||||
|
REFUNDED = "REFUNDED"
|
||||||
|
}
|
||||||
|
export declare enum PaymentProvider {
|
||||||
|
PAYMOB = "PAYMOB",
|
||||||
|
BINANCE = "BINANCE",
|
||||||
|
MANUAL = "MANUAL"
|
||||||
|
}
|
||||||
|
export declare class Transaction {
|
||||||
|
id: string;
|
||||||
|
tenantId: string;
|
||||||
|
subscriptionId: string;
|
||||||
|
amount: number;
|
||||||
|
currency: string;
|
||||||
|
provider: PaymentProvider;
|
||||||
|
externalTransactionId: string;
|
||||||
|
status: PaymentStatus;
|
||||||
|
metadata: Record<string, any>;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
"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.Transaction = exports.PaymentProvider = exports.PaymentStatus = void 0;
|
||||||
|
const typeorm_1 = require("typeorm");
|
||||||
|
var PaymentStatus;
|
||||||
|
(function (PaymentStatus) {
|
||||||
|
PaymentStatus["PENDING"] = "PENDING";
|
||||||
|
PaymentStatus["SUCCESS"] = "SUCCESS";
|
||||||
|
PaymentStatus["FAILED"] = "FAILED";
|
||||||
|
PaymentStatus["REFUNDED"] = "REFUNDED";
|
||||||
|
})(PaymentStatus || (exports.PaymentStatus = PaymentStatus = {}));
|
||||||
|
var PaymentProvider;
|
||||||
|
(function (PaymentProvider) {
|
||||||
|
PaymentProvider["PAYMOB"] = "PAYMOB";
|
||||||
|
PaymentProvider["BINANCE"] = "BINANCE";
|
||||||
|
PaymentProvider["MANUAL"] = "MANUAL";
|
||||||
|
})(PaymentProvider || (exports.PaymentProvider = PaymentProvider = {}));
|
||||||
|
let Transaction = class Transaction {
|
||||||
|
id;
|
||||||
|
tenantId;
|
||||||
|
subscriptionId;
|
||||||
|
amount;
|
||||||
|
currency;
|
||||||
|
provider;
|
||||||
|
externalTransactionId;
|
||||||
|
status;
|
||||||
|
metadata;
|
||||||
|
createdAt;
|
||||||
|
};
|
||||||
|
exports.Transaction = Transaction;
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "id", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
(0, typeorm_1.Column)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "tenantId", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "subscriptionId", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'decimal', precision: 10, scale: 2 }),
|
||||||
|
__metadata("design:type", Number)
|
||||||
|
], Transaction.prototype, "amount", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ default: 'USD' }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "currency", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: PaymentProvider,
|
||||||
|
}),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "provider", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
(0, typeorm_1.Column)({ nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "externalTransactionId", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: PaymentStatus,
|
||||||
|
default: PaymentStatus.PENDING,
|
||||||
|
}),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], Transaction.prototype, "status", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
|
||||||
|
__metadata("design:type", Object)
|
||||||
|
], Transaction.prototype, "metadata", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.CreateDateColumn)(),
|
||||||
|
__metadata("design:type", Date)
|
||||||
|
], Transaction.prototype, "createdAt", void 0);
|
||||||
|
exports.Transaction = Transaction = __decorate([
|
||||||
|
(0, typeorm_1.Entity)('transactions')
|
||||||
|
], Transaction);
|
||||||
|
//# sourceMappingURL=transaction.entity.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"transaction.entity.js","sourceRoot":"","sources":["../../../src/billing/entities/transaction.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAMiB;AAEjB,IAAY,aAKX;AALD,WAAY,aAAa;IACvB,oCAAmB,CAAA;IACnB,oCAAmB,CAAA;IACnB,kCAAiB,CAAA;IACjB,sCAAqB,CAAA;AACvB,CAAC,EALW,aAAa,6BAAb,aAAa,QAKxB;AAED,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,oCAAiB,CAAA;IACjB,sCAAmB,CAAA;IACnB,oCAAiB,CAAA;AACnB,CAAC,EAJW,eAAe,+BAAf,eAAe,QAI1B;AAGM,IAAM,WAAW,GAAjB,MAAM,WAAW;IAEtB,EAAE,CAAS;IAIX,QAAQ,CAAS;IAGjB,cAAc,CAAS;IAGvB,MAAM,CAAS;IAGf,QAAQ,CAAS;IAMjB,QAAQ,CAAkB;IAI1B,qBAAqB,CAAS;IAO9B,MAAM,CAAgB;IAGtB,QAAQ,CAAsB;IAG9B,SAAS,CAAO;CACjB,CAAA;AAvCY,kCAAW;AAEtB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;uCACpB;AAIX;IAFC,IAAA,eAAK,GAAE;IACP,IAAA,gBAAM,GAAE;;6CACQ;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mDACJ;AAGvB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;;2CACtC;AAGf;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;;6CACV;AAMjB;IAJC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,eAAe;KACtB,CAAC;;6CACwB;AAI1B;IAFC,IAAA,eAAK,GAAE;IACP,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;0DACG;AAO9B;IALC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,aAAa,CAAC,OAAO;KAC/B,CAAC;;2CACoB;AAGtB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;6CACZ;AAG9B;IADC,IAAA,0BAAgB,GAAE;8BACR,IAAI;8CAAC;sBAtCL,WAAW;IADvB,IAAA,gBAAM,EAAC,cAAc,CAAC;GACV,WAAW,CAuCvB"}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
export declare class BinanceProvider {
|
||||||
|
private configService;
|
||||||
|
private readonly logger;
|
||||||
|
private readonly apiUrl;
|
||||||
|
constructor(configService: ConfigService);
|
||||||
|
private get apiKey();
|
||||||
|
private get secretKey();
|
||||||
|
private generateSignature;
|
||||||
|
createOrder(tenantId: string, amount: number, plan: string): Promise<{
|
||||||
|
checkoutUrl: any;
|
||||||
|
orderId: string;
|
||||||
|
prepayId: any;
|
||||||
|
}>;
|
||||||
|
verifySignature(timestamp: string, nonce: string, signature: string, payloadBody: any): boolean;
|
||||||
|
}
|
||||||
+150
@@ -0,0 +1,150 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
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 __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
var BinanceProvider_1;
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BinanceProvider = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const config_1 = require("@nestjs/config");
|
||||||
|
const axios_1 = __importDefault(require("axios"));
|
||||||
|
const crypto = __importStar(require("crypto"));
|
||||||
|
let BinanceProvider = BinanceProvider_1 = class BinanceProvider {
|
||||||
|
configService;
|
||||||
|
logger = new common_1.Logger(BinanceProvider_1.name);
|
||||||
|
apiUrl = 'https://bpay.binanceapi.com/binancepay/openapi/v2/order';
|
||||||
|
constructor(configService) {
|
||||||
|
this.configService = configService;
|
||||||
|
}
|
||||||
|
get apiKey() {
|
||||||
|
return this.configService.get('BINANCE_PAY_API_KEY') || '';
|
||||||
|
}
|
||||||
|
get secretKey() {
|
||||||
|
return this.configService.get('BINANCE_PAY_SECRET_KEY') || '';
|
||||||
|
}
|
||||||
|
generateSignature(timestamp, nonce, body) {
|
||||||
|
const payload = timestamp + '\n' + nonce + '\n' + JSON.stringify(body) + '\n';
|
||||||
|
return crypto
|
||||||
|
.createHmac('sha512', this.secretKey)
|
||||||
|
.update(payload)
|
||||||
|
.digest('hex')
|
||||||
|
.toUpperCase();
|
||||||
|
}
|
||||||
|
async createOrder(tenantId, amount, plan) {
|
||||||
|
this.logger.log(`Creating Binance Pay order for ${tenantId} - ${plan}`);
|
||||||
|
if (!this.apiKey || !this.secretKey) {
|
||||||
|
this.logger.error('Binance Pay API keys are not configured');
|
||||||
|
throw new common_1.InternalServerErrorException('Payment provider is not configured properly');
|
||||||
|
}
|
||||||
|
const nonce = crypto.randomBytes(16).toString('hex');
|
||||||
|
const timestamp = Date.now().toString();
|
||||||
|
const merchantTradeNo = `txn_${Date.now()}_${Math.floor(Math.random() * 10000)}`;
|
||||||
|
const body = {
|
||||||
|
env: {
|
||||||
|
terminalType: 'WEB',
|
||||||
|
},
|
||||||
|
merchantTradeNo: merchantTradeNo,
|
||||||
|
orderAmount: amount,
|
||||||
|
currency: 'USDT',
|
||||||
|
goods: {
|
||||||
|
goodsType: '01',
|
||||||
|
goodsCategory: 'Z000',
|
||||||
|
referenceGoodsId: plan,
|
||||||
|
goodsName: `${plan} Plan Subscription`,
|
||||||
|
goodsDetail: `Subscription to ${plan} plan for Maps SaaS`,
|
||||||
|
},
|
||||||
|
passThroughInfo: JSON.stringify({ tenantId, plan }),
|
||||||
|
returnUrl: `https://map-dashboard.intaleqapp.com/dashboard.html#billing`,
|
||||||
|
};
|
||||||
|
const signature = this.generateSignature(timestamp, nonce, body);
|
||||||
|
try {
|
||||||
|
const response = await axios_1.default.post(this.apiUrl, body, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'BinancePay-Timestamp': timestamp,
|
||||||
|
'BinancePay-Nonce': nonce,
|
||||||
|
'BinancePay-Certificate-SN': this.apiKey,
|
||||||
|
'BinancePay-Signature': signature,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (response.data && response.data.status === 'SUCCESS') {
|
||||||
|
return {
|
||||||
|
checkoutUrl: response.data.data.checkoutUrl,
|
||||||
|
orderId: merchantTradeNo,
|
||||||
|
prepayId: response.data.data.prepayId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.logger.error(`Binance API Error: ${JSON.stringify(response.data)}`);
|
||||||
|
throw new common_1.InternalServerErrorException('Failed to create Binance order');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Error communicating with Binance API: ${error.message}`);
|
||||||
|
throw new common_1.InternalServerErrorException('Failed to communicate with payment provider');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verifySignature(timestamp, nonce, signature, payloadBody) {
|
||||||
|
const payload = timestamp + '\n' + nonce + '\n' + JSON.stringify(payloadBody) + '\n';
|
||||||
|
const expectedSignature = crypto
|
||||||
|
.createHmac('sha512', this.secretKey)
|
||||||
|
.update(payload)
|
||||||
|
.digest('hex')
|
||||||
|
.toUpperCase();
|
||||||
|
try {
|
||||||
|
return crypto.timingSafeEqual(Buffer.from(signature || ''), Buffer.from(expectedSignature));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.BinanceProvider = BinanceProvider;
|
||||||
|
exports.BinanceProvider = BinanceProvider = BinanceProvider_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
|
], BinanceProvider);
|
||||||
|
//# sourceMappingURL=binance.provider.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"binance.provider.js","sourceRoot":"","sources":["../../../src/billing/providers/binance.provider.ts"],"names":[],"mappings":"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"}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
export declare class PayMobProvider {
|
||||||
|
private configService;
|
||||||
|
private readonly logger;
|
||||||
|
private readonly baseUrl;
|
||||||
|
constructor(configService: ConfigService);
|
||||||
|
createPaymentKey(tenantId: string, amount: number, plan: string): Promise<{
|
||||||
|
paymentKey: string;
|
||||||
|
orderId: string;
|
||||||
|
}>;
|
||||||
|
getTransactionDetails(transactionId: string): Promise<any>;
|
||||||
|
private getAuthToken;
|
||||||
|
verifyHmac(payload: any, hmac: string): boolean;
|
||||||
|
}
|
||||||
+179
@@ -0,0 +1,179 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
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 __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
var PayMobProvider_1;
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.PayMobProvider = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const config_1 = require("@nestjs/config");
|
||||||
|
const axios_1 = __importDefault(require("axios"));
|
||||||
|
const crypto = __importStar(require("crypto"));
|
||||||
|
let PayMobProvider = PayMobProvider_1 = class PayMobProvider {
|
||||||
|
configService;
|
||||||
|
logger = new common_1.Logger(PayMobProvider_1.name);
|
||||||
|
baseUrl = 'https://accept.paymob.com/api';
|
||||||
|
constructor(configService) {
|
||||||
|
this.configService = configService;
|
||||||
|
}
|
||||||
|
async createPaymentKey(tenantId, amount, plan) {
|
||||||
|
try {
|
||||||
|
const authToken = await this.getAuthToken();
|
||||||
|
const orderRes = await axios_1.default.post(`${this.baseUrl}/ecommerce/orders`, {
|
||||||
|
auth_token: authToken,
|
||||||
|
delivery_needed: "false",
|
||||||
|
amount_cents: amount * 50 * 100,
|
||||||
|
currency: "EGP",
|
||||||
|
items: [{
|
||||||
|
name: `${plan} Subscription`,
|
||||||
|
amount_cents: amount * 50 * 100,
|
||||||
|
description: `Intaleq Maps ${plan} Plan`
|
||||||
|
}],
|
||||||
|
shipping_data: {
|
||||||
|
first_name: "Intaleq",
|
||||||
|
last_name: "User",
|
||||||
|
email: "user@intaleq.com",
|
||||||
|
phone_number: "+201000000000",
|
||||||
|
extra_description: `${tenantId}|${plan}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const orderId = orderRes.data.id;
|
||||||
|
const keyRes = await axios_1.default.post(`${this.baseUrl}/acceptance/payment_keys`, {
|
||||||
|
auth_token: authToken,
|
||||||
|
amount_cents: amount * 50 * 100,
|
||||||
|
expiration: 3600,
|
||||||
|
order_id: orderId,
|
||||||
|
billing_data: {
|
||||||
|
apartment: "NA",
|
||||||
|
email: "user@intaleq.com",
|
||||||
|
floor: "NA",
|
||||||
|
first_name: "Intaleq",
|
||||||
|
street: "NA",
|
||||||
|
building: "NA",
|
||||||
|
phone_number: "+201000000000",
|
||||||
|
shipping_method: "NA",
|
||||||
|
postal_code: "NA",
|
||||||
|
city: "NA",
|
||||||
|
country: "NA",
|
||||||
|
last_name: "User",
|
||||||
|
state: "NA"
|
||||||
|
},
|
||||||
|
currency: "EGP",
|
||||||
|
integration_id: this.configService.get('PAYMOB_INTEGRATION_ID') || 4556055,
|
||||||
|
lock_order_when_paid: "false"
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
paymentKey: keyRes.data.token,
|
||||||
|
orderId: orderId.toString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`PayMob Payment Key failed: ${error.response?.data ? JSON.stringify(error.response.data) : error.message}`);
|
||||||
|
throw new common_1.BadRequestException('Failed to initialize PayMob payment');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getTransactionDetails(transactionId) {
|
||||||
|
try {
|
||||||
|
const authToken = await this.getAuthToken();
|
||||||
|
const res = await axios_1.default.get(`${this.baseUrl}/acceptance/transactions/${transactionId}`, {
|
||||||
|
headers: { Authorization: `Bearer ${authToken}` }
|
||||||
|
});
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Failed to fetch PayMob transaction ${transactionId}: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getAuthToken() {
|
||||||
|
const authRes = await axios_1.default.post(`${this.baseUrl}/auth/tokens`, {
|
||||||
|
api_key: this.configService.get('PAYMOB_API_KEY'),
|
||||||
|
});
|
||||||
|
return authRes.data.token;
|
||||||
|
}
|
||||||
|
verifyHmac(payload, hmac) {
|
||||||
|
const secret = this.configService.get('PAYMOB_HMAC_SECRET');
|
||||||
|
if (!secret)
|
||||||
|
return false;
|
||||||
|
const { amount_cents, created_at, currency, error_occured, has_parent_transaction, id, integration_id, is_3d_secure, is_auth, is_capture, is_refunded, is_standalone_payment, is_voided, order, owner, pending, success } = payload;
|
||||||
|
const source_pan = payload.source_data?.pan || "";
|
||||||
|
const source_sub_type = payload.source_data?.sub_type || "";
|
||||||
|
const source_type = payload.source_data?.type || "";
|
||||||
|
const data = [
|
||||||
|
amount_cents,
|
||||||
|
created_at,
|
||||||
|
currency,
|
||||||
|
error_occured,
|
||||||
|
has_parent_transaction,
|
||||||
|
id,
|
||||||
|
integration_id,
|
||||||
|
is_3d_secure,
|
||||||
|
is_auth,
|
||||||
|
is_capture,
|
||||||
|
is_refunded,
|
||||||
|
is_standalone_payment,
|
||||||
|
is_voided,
|
||||||
|
order.id || order,
|
||||||
|
owner,
|
||||||
|
pending,
|
||||||
|
source_pan,
|
||||||
|
source_sub_type,
|
||||||
|
source_type,
|
||||||
|
success
|
||||||
|
].join("");
|
||||||
|
const hash = crypto
|
||||||
|
.createHmac('sha512', secret)
|
||||||
|
.update(data)
|
||||||
|
.digest('hex');
|
||||||
|
return hash === hmac;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.PayMobProvider = PayMobProvider;
|
||||||
|
exports.PayMobProvider = PayMobProvider = PayMobProvider_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
|
], PayMobProvider);
|
||||||
|
//# sourceMappingURL=paymob.provider.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"paymob.provider.js","sourceRoot":"","sources":["../../../src/billing/providers/paymob.provider.ts"],"names":[],"mappings":"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"}
|
||||||
+2
-1
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
};
|
};
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.CacheService = void 0;
|
exports.CacheService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -38,6 +39,6 @@ let CacheService = class CacheService {
|
|||||||
exports.CacheService = CacheService;
|
exports.CacheService = CacheService;
|
||||||
exports.CacheService = CacheService = __decorate([
|
exports.CacheService = CacheService = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__metadata("design:paramtypes", [config_1.ConfigService])
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
], CacheService);
|
], CacheService);
|
||||||
//# sourceMappingURL=cache.service.js.map
|
//# sourceMappingURL=cache.service.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"cache.service.js","sourceRoot":"","sources":["../../src/common/cache.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAoD;AACpD,iCAAqC;AACrC,2CAA+C;AAGxC,IAAM,YAAY,GAAlB,MAAM,YAAY;IAGH;IAFZ,MAAM,CAAC;IAEf,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAA,oBAAY,EAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,aAAqB,IAAI;QAG1D,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChD,EAAE,EAAE,UAAU;SACf,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QAGnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF,CAAA;AA3BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAIwB,sBAAa;GAHrC,YAAY,CA2BxB"}
|
{"version":3,"file":"cache.service.js","sourceRoot":"","sources":["../../src/common/cache.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,iCAAqC;AACrC,2CAA+C;AAGxC,IAAM,YAAY,GAAlB,MAAM,YAAY;IAGH;IAFZ,MAAM,CAAC;IAEf,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAA,oBAAY,EAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,aAAqB,IAAI;QAG1D,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChD,EAAE,EAAE,UAAU;SACf,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QAGnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;CACF,CAAA;AA3BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;yDAIwB,sBAAa,oBAAb,sBAAa;GAHrC,YAAY,CA2BxB"}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||||
|
export declare class AdminGuard implements CanActivate {
|
||||||
|
canActivate(context: ExecutionContext): boolean;
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
"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.AdminGuard = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const tenant_entity_1 = require("../../auth/entities/tenant.entity");
|
||||||
|
let AdminGuard = class AdminGuard {
|
||||||
|
canActivate(context) {
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
const tenant = request['tenant'];
|
||||||
|
if (!tenant) {
|
||||||
|
throw new common_1.UnauthorizedException('Tenant not found in request');
|
||||||
|
}
|
||||||
|
if (tenant.plan !== tenant_entity_1.TenantPlan.ENTERPRISE) {
|
||||||
|
throw new common_1.ForbiddenException('Admin access required. Your tenant plan must be ENTERPRISE.');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.AdminGuard = AdminGuard;
|
||||||
|
exports.AdminGuard = AdminGuard = __decorate([
|
||||||
|
(0, common_1.Injectable)()
|
||||||
|
], AdminGuard);
|
||||||
|
//# sourceMappingURL=admin.guard.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"admin.guard.js","sourceRoot":"","sources":["../../../src/common/guards/admin.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAsH;AACtH,qEAA+D;AAGxD,IAAM,UAAU,GAAhB,MAAM,UAAU;IACrB,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,8BAAqB,CAAC,6BAA6B,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,0BAAU,CAAC,UAAU,EAAE,CAAC;YAC1C,MAAM,IAAI,2BAAkB,CAAC,6DAA6D,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAfY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;GACA,UAAU,CAetB"}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ThrottlerGuard, ThrottlerRequest } from '@nestjs/throttler';
|
import { ThrottlerGuard, ThrottlerRequest } from '@nestjs/throttler';
|
||||||
export declare class TenantThrottlerGuard extends ThrottlerGuard {
|
export declare class TenantThrottlerGuard extends ThrottlerGuard {
|
||||||
|
private readonly logger;
|
||||||
protected getTracker(req: Record<string, any>): Promise<string>;
|
protected getTracker(req: Record<string, any>): Promise<string>;
|
||||||
protected handleRequest(requestProps: ThrottlerRequest): Promise<boolean>;
|
protected handleRequest(requestProps: ThrottlerRequest): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-4
@@ -5,25 +5,33 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||||||
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;
|
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;
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||||
};
|
};
|
||||||
|
var TenantThrottlerGuard_1;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.TenantThrottlerGuard = void 0;
|
exports.TenantThrottlerGuard = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
const throttler_1 = require("@nestjs/throttler");
|
const throttler_1 = require("@nestjs/throttler");
|
||||||
let TenantThrottlerGuard = class TenantThrottlerGuard extends throttler_1.ThrottlerGuard {
|
let TenantThrottlerGuard = TenantThrottlerGuard_1 = class TenantThrottlerGuard extends throttler_1.ThrottlerGuard {
|
||||||
|
logger = new common_1.Logger(TenantThrottlerGuard_1.name);
|
||||||
async getTracker(req) {
|
async getTracker(req) {
|
||||||
const apiKeyId = req['apiKey']?.id || req.ip;
|
const apiKeyId = req['apiKey']?.id || req.ip;
|
||||||
return `throttler:key:${apiKeyId}`;
|
return `throttler:key:${apiKeyId}`;
|
||||||
}
|
}
|
||||||
async handleRequest(requestProps) {
|
async handleRequest(requestProps) {
|
||||||
const { context, limit } = requestProps;
|
const { context, limit, ttl } = requestProps;
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
const dynamicLimit = request['rateLimit'] || limit;
|
const dynamicLimit = request['rateLimit'];
|
||||||
|
if (dynamicLimit) {
|
||||||
|
this.logger.debug(`Applying dynamic rate limit: ${dynamicLimit} req/min for key ${request['apiKey']?.id}`);
|
||||||
requestProps.limit = dynamicLimit;
|
requestProps.limit = dynamicLimit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.logger.debug(`Applying default rate limit: ${limit} req/min`);
|
||||||
|
}
|
||||||
return super.handleRequest(requestProps);
|
return super.handleRequest(requestProps);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
exports.TenantThrottlerGuard = TenantThrottlerGuard;
|
exports.TenantThrottlerGuard = TenantThrottlerGuard;
|
||||||
exports.TenantThrottlerGuard = TenantThrottlerGuard = __decorate([
|
exports.TenantThrottlerGuard = TenantThrottlerGuard = TenantThrottlerGuard_1 = __decorate([
|
||||||
(0, common_1.Injectable)()
|
(0, common_1.Injectable)()
|
||||||
], TenantThrottlerGuard);
|
], TenantThrottlerGuard);
|
||||||
//# sourceMappingURL=rate-limiter.guard.js.map
|
//# sourceMappingURL=rate-limiter.guard.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"rate-limiter.guard.js","sourceRoot":"","sources":["../../../src/common/guards/rate-limiter.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA8D;AAC9D,iDAAqE;AAG9D,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,0BAAc;IAK5C,KAAK,CAAC,UAAU,CAAC,GAAwB;QAEjD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,iBAAiB,QAAQ,EAAE,CAAC;IACrC,CAAC;IAKS,KAAK,CAAC,aAAa,CAC3B,YAA8B;QAE9B,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC;QACxC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAGpD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;QAGnD,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC;QAGlC,OAAO,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AA7BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;GACA,oBAAoB,CA6BhC"}
|
{"version":3,"file":"rate-limiter.guard.js","sourceRoot":"","sources":["../../../src/common/guards/rate-limiter.guard.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAsE;AACtE,iDAAqE;AAG9D,IAAM,oBAAoB,4BAA1B,MAAM,oBAAqB,SAAQ,0BAAc;IACrC,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;IAEtD,KAAK,CAAC,UAAU,CAAC,GAAwB;QACjD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,iBAAiB,QAAQ,EAAE,CAAC;IACrC,CAAC;IAES,KAAK,CAAC,aAAa,CAC3B,YAA8B;QAE9B,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAGpD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAE1C,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,YAAY,oBAAoB,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3G,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,KAAK,UAAU,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AA1BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;GACA,oBAAoB,CA0BhC"}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
export declare class MailModule {
|
||||||
|
}
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
"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.MailModule = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const mail_service_1 = require("./mail.service");
|
||||||
|
let MailModule = class MailModule {
|
||||||
|
};
|
||||||
|
exports.MailModule = MailModule;
|
||||||
|
exports.MailModule = MailModule = __decorate([
|
||||||
|
(0, common_1.Global)(),
|
||||||
|
(0, common_1.Module)({
|
||||||
|
providers: [mail_service_1.MailService],
|
||||||
|
exports: [mail_service_1.MailService],
|
||||||
|
})
|
||||||
|
], MailModule);
|
||||||
|
//# sourceMappingURL=mail.module.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"mail.module.js","sourceRoot":"","sources":["../../src/common/mail.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,iDAA6C;AAOtC,IAAM,UAAU,GAAhB,MAAM,UAAU;CAAG,CAAA;AAAb,gCAAU;qBAAV,UAAU;IALtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,0BAAW,CAAC;QACxB,OAAO,EAAE,CAAC,0BAAW,CAAC;KACvB,CAAC;GACW,UAAU,CAAG"}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
export declare class MailService {
|
||||||
|
private configService;
|
||||||
|
private readonly logger;
|
||||||
|
private transporter;
|
||||||
|
constructor(configService: ConfigService);
|
||||||
|
sendInvoiceEmail(to: string, data: {
|
||||||
|
tenantName: string;
|
||||||
|
plan: string;
|
||||||
|
amount: string;
|
||||||
|
transactionId: string;
|
||||||
|
}): Promise<boolean>;
|
||||||
|
}
|
||||||
Vendored
+122
@@ -0,0 +1,122 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
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 __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
|
};
|
||||||
|
var MailService_1;
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.MailService = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const config_1 = require("@nestjs/config");
|
||||||
|
const nodemailer = __importStar(require("nodemailer"));
|
||||||
|
let MailService = MailService_1 = class MailService {
|
||||||
|
configService;
|
||||||
|
logger = new common_1.Logger(MailService_1.name);
|
||||||
|
transporter;
|
||||||
|
constructor(configService) {
|
||||||
|
this.configService = configService;
|
||||||
|
const host = this.configService.get('SMTP_HOST');
|
||||||
|
const port = this.configService.get('SMTP_PORT') || 587;
|
||||||
|
const user = this.configService.get('SMTP_USER');
|
||||||
|
const pass = this.configService.get('SMTP_PASS');
|
||||||
|
if (host && user && pass) {
|
||||||
|
this.transporter = nodemailer.createTransport({
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
secure: port === 465,
|
||||||
|
auth: {
|
||||||
|
user,
|
||||||
|
pass,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.logger.log(`📧 MailService initialized with host: ${host}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.logger.warn('⚠️ SMTP settings not fully configured. MailService will run in mock mode.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async sendInvoiceEmail(to, data) {
|
||||||
|
const from = this.configService.get('SMTP_FROM') || 'support@intaleqapp.com';
|
||||||
|
const htmlContent = `
|
||||||
|
<div style="font-family: sans-serif; max-width: 600px; margin: auto; border: 1px solid #eee; padding: 20px; border-radius: 10px;">
|
||||||
|
<h2 style="color: #2563eb;">Intaleq Maps - Payment Successful</h2>
|
||||||
|
<p>Hello <b>${data.tenantName}</b>,</p>
|
||||||
|
<p>Thank you for subscribing to our <b>${data.plan}</b> plan. Your payment has been processed successfully.</p>
|
||||||
|
|
||||||
|
<div style="background: #f8fafc; padding: 15px; border-radius: 8px; margin: 20px 0;">
|
||||||
|
<p style="margin: 5px 0;"><b>Plan:</b> ${data.plan}</p>
|
||||||
|
<p style="margin: 5px 0;"><b>Amount:</b> ${data.amount}</p>
|
||||||
|
<p style="margin: 5px 0;"><b>Transaction ID:</b> ${data.transactionId}</p>
|
||||||
|
<p style="margin: 5px 0;"><b>Date:</b> ${new Date().toLocaleDateString()}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>You can now access all your premium features from your dashboard.</p>
|
||||||
|
<hr style="border: none; border-top: 1px solid #eee; margin: 20px 0;">
|
||||||
|
<p style="font-size: 12px; color: #64748b;">If you have any questions, contact us at ${from}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
if (!this.transporter) {
|
||||||
|
this.logger.warn(`[Mock Email] To: ${to}, Plan: ${data.plan}, Amount: ${data.amount}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.transporter.sendMail({
|
||||||
|
from: `"Intaleq Support" <${from}>`,
|
||||||
|
to,
|
||||||
|
subject: `Invoice: ${data.plan} Subscription - Intaleq Maps`,
|
||||||
|
html: htmlContent,
|
||||||
|
});
|
||||||
|
this.logger.log(`✅ Invoice email sent to ${to}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`❌ Failed to send email: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.MailService = MailService;
|
||||||
|
exports.MailService = MailService = MailService_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
|
], MailService);
|
||||||
|
//# sourceMappingURL=mail.service.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"mail.service.js","sourceRoot":"","sources":["../../src/common/mail.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2CAA+C;AAC/C,uDAAyC;AAGlC,IAAM,WAAW,mBAAjB,MAAM,WAAW;IAIF;IAHH,MAAM,GAAG,IAAI,eAAM,CAAC,aAAW,CAAC,IAAI,CAAC,CAAC;IAC/C,WAAW,CAAyB;IAE5C,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,CAAC,IAAI,GAAG,CAAC;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,CAAC,CAAC;QAEzD,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,eAAe,CAAC;gBAC5C,IAAI;gBACJ,IAAI;gBACJ,MAAM,EAAE,IAAI,KAAK,GAAG;gBACpB,IAAI,EAAE;oBACJ,IAAI;oBACJ,IAAI;iBACL;aACF,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EAAU,EAAE,IAKlC;QACC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,CAAC,IAAI,wBAAwB,CAAC;QAErF,MAAM,WAAW,GAAG;;;sBAGF,IAAI,CAAC,UAAU;iDACY,IAAI,CAAC,IAAI;;;mDAGP,IAAI,CAAC,IAAI;qDACP,IAAI,CAAC,MAAM;6DACH,IAAI,CAAC,aAAa;mDAC5B,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE;;;;;+FAKa,IAAI;;KAE9F,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,IAAI,CAAC,IAAI,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACvF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;gBAC9B,IAAI,EAAE,sBAAsB,IAAI,GAAG;gBACnC,EAAE;gBACF,OAAO,EAAE,YAAY,IAAI,CAAC,IAAI,8BAA8B;gBAC5D,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF,CAAA;AAxEY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;yDAKwB,sBAAa,oBAAb,sBAAa;GAJrC,WAAW,CAwEvB"}
|
||||||
+1
@@ -3,6 +3,7 @@ import type { RedisClientType } from 'redis';
|
|||||||
export declare class RedisService implements OnModuleDestroy {
|
export declare class RedisService implements OnModuleDestroy {
|
||||||
private readonly redisClient;
|
private readonly redisClient;
|
||||||
constructor(redisClient: RedisClientType);
|
constructor(redisClient: RedisClientType);
|
||||||
|
getClient(): RedisClientType;
|
||||||
set(key: string, value: any, ttlSeconds?: number): Promise<void>;
|
set(key: string, value: any, ttlSeconds?: number): Promise<void>;
|
||||||
get<T>(key: string): Promise<T | null>;
|
get<T>(key: string): Promise<T | null>;
|
||||||
del(key: string): Promise<void>;
|
del(key: string): Promise<void>;
|
||||||
|
|||||||
+3
@@ -19,6 +19,9 @@ let RedisService = class RedisService {
|
|||||||
constructor(redisClient) {
|
constructor(redisClient) {
|
||||||
this.redisClient = redisClient;
|
this.redisClient = redisClient;
|
||||||
}
|
}
|
||||||
|
getClient() {
|
||||||
|
return this.redisClient;
|
||||||
|
}
|
||||||
async set(key, value, ttlSeconds) {
|
async set(key, value, ttlSeconds) {
|
||||||
const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
|
const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
|
||||||
if (ttlSeconds) {
|
if (ttlSeconds) {
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"redis.service.js","sourceRoot":"","sources":["../../src/common/redis.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAqE;AAS9D,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEoB;IAD3C,YAC2C,WAA4B;QAA5B,gBAAW,GAAX,WAAW,CAAiB;IACpE,CAAC;IAMJ,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,UAAmB;QACpD,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9E,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;CACF,CAAA;AA5CY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,cAAc,CAAC,CAAA;;GAFd,YAAY,CA4CxB"}
|
{"version":3,"file":"redis.service.js","sourceRoot":"","sources":["../../src/common/redis.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAqE;AAS9D,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEoB;IAD3C,YAC2C,WAA4B;QAA5B,gBAAW,GAAX,WAAW,CAAiB;IACpE,CAAC;IAKJ,SAAS;QACP,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAMD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,UAAmB;QACpD,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9E,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,GAAG,CAAI,GAAW;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAqB,CAAC;QAC/B,CAAC;IACH,CAAC;IAMD,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;CACF,CAAA;AAnDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,cAAc,CAAC,CAAA;;GAFd,YAAY,CAmDxB"}
|
||||||
+2
-1
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
var TelegramService_1;
|
var TelegramService_1;
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.TelegramService = void 0;
|
exports.TelegramService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -70,6 +71,6 @@ let TelegramService = TelegramService_1 = class TelegramService {
|
|||||||
exports.TelegramService = TelegramService;
|
exports.TelegramService = TelegramService;
|
||||||
exports.TelegramService = TelegramService = TelegramService_1 = __decorate([
|
exports.TelegramService = TelegramService = TelegramService_1 = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__metadata("design:paramtypes", [config_1.ConfigService])
|
__metadata("design:paramtypes", [typeof (_a = typeof config_1.ConfigService !== "undefined" && config_1.ConfigService) === "function" ? _a : Object])
|
||||||
], TelegramService);
|
], TelegramService);
|
||||||
//# sourceMappingURL=telegram.service.js.map
|
//# sourceMappingURL=telegram.service.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"telegram.service.js","sourceRoot":"","sources":["../../src/common/telegram.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2CAA+C;AAC/C,kDAA0B;AAGnB,IAAM,eAAe,uBAArB,MAAM,eAAe;IAKN;IAJH,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,QAAQ,CAAS;IACjB,MAAM,CAAS;IAEhC,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,oBAAoB,CAAC,IAAI,EAAE,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACzE,CAAC;IAMD,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YACzF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,+BAA+B,IAAI,CAAC,QAAQ,cAAc,CAAC;YACvE,MAAM,eAAK,CAAC,IAAI,CAAC,GAAG,EAAE;gBACpB,OAAO,EAAE,IAAI,CAAC,MAAM;gBACpB,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,MAAM;aACnB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,QAAQ,CAAC,MAAM,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtG,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,sBAAsB,CAAC,KAO5B;QACC,MAAM,OAAO,GAAG;;;yBAGK,KAAK,CAAC,IAAI;6BACN,KAAK,CAAC,UAAU;4BACjB,KAAK,CAAC,eAAe;4BACrB,KAAK,CAAC,eAAe;2BACtB,KAAK,CAAC,YAAY,IAAI,CAAC;4BACtB,KAAK,CAAC,WAAW;;;KAGxC,CAAC;QACF,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACF,CAAA;AAhEY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAMwB,sBAAa;GALrC,eAAe,CAgE3B"}
|
{"version":3,"file":"telegram.service.js","sourceRoot":"","sources":["../../src/common/telegram.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2CAA+C;AAC/C,kDAA0B;AAGnB,IAAM,eAAe,uBAArB,MAAM,eAAe;IAKN;IAJH,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,QAAQ,CAAS;IACjB,MAAM,CAAS;IAEhC,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,oBAAoB,CAAC,IAAI,EAAE,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACzE,CAAC;IAMD,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YACzF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,+BAA+B,IAAI,CAAC,QAAQ,cAAc,CAAC;YACvE,MAAM,eAAK,CAAC,IAAI,CAAC,GAAG,EAAE;gBACpB,OAAO,EAAE,IAAI,CAAC,MAAM;gBACpB,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,MAAM;aACnB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,QAAQ,CAAC,MAAM,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtG,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,sBAAsB,CAAC,KAO5B;QACC,MAAM,OAAO,GAAG;;;yBAGK,KAAK,CAAC,IAAI;6BACN,KAAK,CAAC,UAAU;4BACjB,KAAK,CAAC,eAAe;4BACrB,KAAK,CAAC,eAAe;2BACtB,KAAK,CAAC,YAAY,IAAI,CAAC;4BACtB,KAAK,CAAC,WAAW;;;KAGxC,CAAC;QACF,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACF,CAAA;AAhEY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;yDAMwB,sBAAa,oBAAb,sBAAa;GALrC,eAAe,CAgE3B"}
|
||||||
+2
-1
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
return function (target, key) { decorator(target, key, paramIndex); }
|
||||||
};
|
};
|
||||||
var AdminBoundariesService_1;
|
var AdminBoundariesService_1;
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.AdminBoundariesService = void 0;
|
exports.AdminBoundariesService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -132,6 +133,6 @@ exports.AdminBoundariesService = AdminBoundariesService;
|
|||||||
exports.AdminBoundariesService = AdminBoundariesService = AdminBoundariesService_1 = __decorate([
|
exports.AdminBoundariesService = AdminBoundariesService = AdminBoundariesService_1 = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__param(0, (0, typeorm_1.InjectRepository)(admin_boundary_entity_1.AdminBoundary)),
|
__param(0, (0, typeorm_1.InjectRepository)(admin_boundary_entity_1.AdminBoundary)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.Repository])
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object])
|
||||||
], AdminBoundariesService);
|
], AdminBoundariesService);
|
||||||
//# sourceMappingURL=admin-boundaries.service.js.map
|
//# sourceMappingURL=admin-boundaries.service.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"admin-boundaries.service.js","sourceRoot":"","sources":["../../src/geocoding/admin-boundaries.service.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"admin-boundaries.service.js","sourceRoot":"","sources":["../../src/geocoding/admin-boundaries.service.ts"],"names":[],"mappings":"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"}
|
||||||
@@ -15,6 +15,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
var AdministrativeLinkingService_1;
|
var AdministrativeLinkingService_1;
|
||||||
|
var _a, _b, _c, _d;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.AdministrativeLinkingService = void 0;
|
exports.AdministrativeLinkingService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -277,9 +278,6 @@ exports.AdministrativeLinkingService = AdministrativeLinkingService = Administra
|
|||||||
__param(1, (0, typeorm_1.InjectRepository)(neighborhood_point_entity_1.NeighborhoodPoint)),
|
__param(1, (0, typeorm_1.InjectRepository)(neighborhood_point_entity_1.NeighborhoodPoint)),
|
||||||
__param(2, (0, typeorm_1.InjectRepository)(neighborhood_polygon_entity_1.NeighborhoodPolygon)),
|
__param(2, (0, typeorm_1.InjectRepository)(neighborhood_polygon_entity_1.NeighborhoodPolygon)),
|
||||||
__param(3, (0, typeorm_1.InjectRepository)(admin_boundary_entity_1.AdminBoundary)),
|
__param(3, (0, typeorm_1.InjectRepository)(admin_boundary_entity_1.AdminBoundary)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.DataSource,
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.DataSource !== "undefined" && typeorm_2.DataSource) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, typeof (_c = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _c : Object, typeof (_d = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _d : Object])
|
||||||
typeorm_2.Repository,
|
|
||||||
typeorm_2.Repository,
|
|
||||||
typeorm_2.Repository])
|
|
||||||
], AdministrativeLinkingService);
|
], AdministrativeLinkingService);
|
||||||
//# sourceMappingURL=administrative-linking.service.js.map
|
//# sourceMappingURL=administrative-linking.service.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
|||||||
|
import { BasePlace } from './base-place.entity';
|
||||||
|
export declare enum CandidateStatus {
|
||||||
|
PENDING = "PENDING",
|
||||||
|
APPROVED = "APPROVED",
|
||||||
|
REJECTED = "REJECTED"
|
||||||
|
}
|
||||||
|
export declare enum CountryCode {
|
||||||
|
JORDAN = "JORDAN",
|
||||||
|
SYRIA = "SYRIA",
|
||||||
|
EGYPT = "EGYPT"
|
||||||
|
}
|
||||||
|
export declare class MapCandidate extends BasePlace {
|
||||||
|
status: CandidateStatus;
|
||||||
|
submittedBy: string;
|
||||||
|
rejectionReason: string;
|
||||||
|
country: CountryCode;
|
||||||
|
metadata: any;
|
||||||
|
verified_name: string;
|
||||||
|
confidence_score: number;
|
||||||
|
verification_metadata: any;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
"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.MapCandidate = exports.CountryCode = exports.CandidateStatus = void 0;
|
||||||
|
const typeorm_1 = require("typeorm");
|
||||||
|
const base_place_entity_1 = require("./base-place.entity");
|
||||||
|
var CandidateStatus;
|
||||||
|
(function (CandidateStatus) {
|
||||||
|
CandidateStatus["PENDING"] = "PENDING";
|
||||||
|
CandidateStatus["APPROVED"] = "APPROVED";
|
||||||
|
CandidateStatus["REJECTED"] = "REJECTED";
|
||||||
|
})(CandidateStatus || (exports.CandidateStatus = CandidateStatus = {}));
|
||||||
|
var CountryCode;
|
||||||
|
(function (CountryCode) {
|
||||||
|
CountryCode["JORDAN"] = "JORDAN";
|
||||||
|
CountryCode["SYRIA"] = "SYRIA";
|
||||||
|
CountryCode["EGYPT"] = "EGYPT";
|
||||||
|
})(CountryCode || (exports.CountryCode = CountryCode = {}));
|
||||||
|
let MapCandidate = class MapCandidate extends base_place_entity_1.BasePlace {
|
||||||
|
status;
|
||||||
|
submittedBy;
|
||||||
|
rejectionReason;
|
||||||
|
country;
|
||||||
|
metadata;
|
||||||
|
verified_name;
|
||||||
|
confidence_score;
|
||||||
|
verification_metadata;
|
||||||
|
};
|
||||||
|
exports.MapCandidate = MapCandidate;
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: CandidateStatus,
|
||||||
|
default: CandidateStatus.PENDING
|
||||||
|
}),
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], MapCandidate.prototype, "status", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ nullable: true }),
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], MapCandidate.prototype, "submittedBy", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], MapCandidate.prototype, "rejectionReason", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({
|
||||||
|
type: 'enum',
|
||||||
|
enum: CountryCode,
|
||||||
|
default: CountryCode.JORDAN
|
||||||
|
}),
|
||||||
|
(0, typeorm_1.Index)(),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], MapCandidate.prototype, "country", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
|
||||||
|
__metadata("design:type", Object)
|
||||||
|
], MapCandidate.prototype, "metadata", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], MapCandidate.prototype, "verified_name", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
|
||||||
|
__metadata("design:type", Number)
|
||||||
|
], MapCandidate.prototype, "confidence_score", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
|
||||||
|
__metadata("design:type", Object)
|
||||||
|
], MapCandidate.prototype, "verification_metadata", void 0);
|
||||||
|
exports.MapCandidate = MapCandidate = __decorate([
|
||||||
|
(0, typeorm_1.Entity)('map_candidates')
|
||||||
|
], MapCandidate);
|
||||||
|
//# sourceMappingURL=map-candidate.entity.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"map-candidate.entity.js","sourceRoot":"","sources":["../../../src/geocoding/entities/map-candidate.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAgD;AAChD,2DAAgD;AAEhD,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,wCAAqB,CAAA;IACrB,wCAAqB,CAAA;AACvB,CAAC,EAJW,eAAe,+BAAf,eAAe,QAI1B;AAED,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,8BAAe,CAAA;IACf,8BAAe,CAAA;AACjB,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,6BAAS;IAOzC,MAAM,CAAkB;IAIxB,WAAW,CAAS;IAGpB,eAAe,CAAS;IAQxB,OAAO,CAAc;IAGrB,QAAQ,CAAM;IAGd,aAAa,CAAS;IAGtB,gBAAgB,CAAS;IAGzB,qBAAqB,CAAM;CAC5B,CAAA;AAnCY,oCAAY;AAOvB;IANC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,eAAe,CAAC,OAAO;KACjC,CAAC;IACD,IAAA,eAAK,GAAE;;4CACgB;AAIxB;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1B,IAAA,eAAK,GAAE;;iDACY;AAGpB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;qDACjB;AAQxB;IANC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,WAAW,CAAC,MAAM;KAC5B,CAAC;IACD,IAAA,eAAK,GAAE;;6CACa;AAGrB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CAC5B;AAGd;IADC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mDACL;AAGtB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;sDACX;AAGzB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2DACf;uBAlChB,YAAY;IADxB,IAAA,gBAAM,EAAC,gBAAgB,CAAC;GACZ,YAAY,CAmCxB"}
|
||||||
+2
-1
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
return function (target, key) { decorator(target, key, paramIndex); }
|
||||||
};
|
};
|
||||||
var GeocodingInitService_1;
|
var GeocodingInitService_1;
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.GeocodingInitService = void 0;
|
exports.GeocodingInitService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -99,6 +100,6 @@ exports.GeocodingInitService = GeocodingInitService;
|
|||||||
exports.GeocodingInitService = GeocodingInitService = GeocodingInitService_1 = __decorate([
|
exports.GeocodingInitService = GeocodingInitService = GeocodingInitService_1 = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__param(0, (0, typeorm_1.InjectRepository)(place_syria_entity_1.PlaceSyria)),
|
__param(0, (0, typeorm_1.InjectRepository)(place_syria_entity_1.PlaceSyria)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.Repository])
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object])
|
||||||
], GeocodingInitService);
|
], GeocodingInitService);
|
||||||
//# sourceMappingURL=geocoding-init.service.js.map
|
//# sourceMappingURL=geocoding-init.service.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"geocoding-init.service.js","sourceRoot":"","sources":["../../src/geocoding/geocoding-init.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAkE;AAClE,6CAAmD;AACnD,qCAAqC;AACrC,sEAA2D;AAGpD,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IAKZ;IAJF,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhE,YAEmB,IAA4B;QAA5B,SAAI,GAAJ,IAAI,CAAwB;IAC5C,CAAC;IAEJ,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACnE,IAAI,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACjE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAGjE,MAAM,MAAM,GAAG,CAAC,eAAe,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;YACjE,MAAM,aAAa,GAAG;gBACpB,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,EAAE;gBACjD,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,EAAE;gBAC9C,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,iBAAiB,EAAE;gBAClD,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,iBAAiB,EAAE;aACpD,CAAC;YAEF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;oBACpC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;wFAGwD,KAAK,wBAAwB,OAAO,CAAC,GAAG;8BAClG,KAAK,kBAAkB,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,GAAG;;;WAGvE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAGD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;OAiBrB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAGH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAGH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;YACvH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YAGrH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qIAAqI,CAAC,CAAC;YAC7J,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mIAAmI,CAAC,CAAC;YAE3J,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;QACjH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mDAAmD,EAAE,GAAG,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;CACF,CAAA;AA5FY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,0BAAgB,EAAC,+BAAU,CAAC,CAAA;qCACN,oBAAU;GALxB,oBAAoB,CA4FhC"}
|
{"version":3,"file":"geocoding-init.service.js","sourceRoot":"","sources":["../../src/geocoding/geocoding-init.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAAkE;AAClE,6CAAmD;AACnD,qCAAqC;AACrC,sEAA2D;AAGpD,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IAKZ;IAJF,MAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhE,YAEmB,IAA4B;QAA5B,SAAI,GAAJ,IAAI,CAAwB;IAC5C,CAAC;IAEJ,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACnE,IAAI,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACjE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAGjE,MAAM,MAAM,GAAG,CAAC,eAAe,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;YACjE,MAAM,aAAa,GAAG;gBACpB,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,EAAE;gBACjD,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,EAAE;gBAC9C,EAAE,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,iBAAiB,EAAE;gBAClD,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,iBAAiB,EAAE;aACpD,CAAC;YAEF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;oBACpC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;wFAGwD,KAAK,wBAAwB,OAAO,CAAC,GAAG;8BAClG,KAAK,kBAAkB,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,GAAG;;;WAGvE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAGD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;OAiBrB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAGH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;OAKrB,CAAC,CAAC;YAGH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;YACvH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YAGrH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qIAAqI,CAAC,CAAC;YAC7J,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mIAAmI,CAAC,CAAC;YAE3J,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;QACjH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mDAAmD,EAAE,GAAG,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;CACF,CAAA;AA5FY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,0BAAgB,EAAC,+BAAU,CAAC,CAAA;yDACN,oBAAU,oBAAV,oBAAU;GALxB,oBAAoB,CA4FhC"}
|
||||||
+19
-23
@@ -2,6 +2,7 @@ import { GeocodingService } from './geocoding.service';
|
|||||||
import { AdminBoundariesService } from './admin-boundaries.service';
|
import { AdminBoundariesService } from './admin-boundaries.service';
|
||||||
import { JordanResearchService } from './jordan-research.service';
|
import { JordanResearchService } from './jordan-research.service';
|
||||||
import { AdministrativeLinkingService } from './administrative-linking.service';
|
import { AdministrativeLinkingService } from './administrative-linking.service';
|
||||||
|
import { MapRefinementService } from './map-refinement.service';
|
||||||
import { SearchQueryDto } from './dto/search-query.dto';
|
import { SearchQueryDto } from './dto/search-query.dto';
|
||||||
import { ReverseGeocodeDto } from './dto/reverse-geocode.dto';
|
import { ReverseGeocodeDto } from './dto/reverse-geocode.dto';
|
||||||
export declare class GeocodingController {
|
export declare class GeocodingController {
|
||||||
@@ -9,38 +10,33 @@ export declare class GeocodingController {
|
|||||||
private readonly adminBoundariesService;
|
private readonly adminBoundariesService;
|
||||||
private readonly jordanResearchService;
|
private readonly jordanResearchService;
|
||||||
private readonly adminLinkingService;
|
private readonly adminLinkingService;
|
||||||
constructor(geocodingService: GeocodingService, adminBoundariesService: AdminBoundariesService, jordanResearchService: JordanResearchService, adminLinkingService: AdministrativeLinkingService);
|
private readonly refinementService;
|
||||||
|
constructor(geocodingService: GeocodingService, adminBoundariesService: AdminBoundariesService, jordanResearchService: JordanResearchService, adminLinkingService: AdministrativeLinkingService, refinementService: MapRefinementService);
|
||||||
search(queryDto: SearchQueryDto): Promise<{
|
search(queryDto: SearchQueryDto): Promise<{
|
||||||
results: any;
|
results: any;
|
||||||
source: string;
|
source: string;
|
||||||
|
did_you_mean?: undefined;
|
||||||
|
} | {
|
||||||
|
results: never[];
|
||||||
|
did_you_mean: any;
|
||||||
|
source?: undefined;
|
||||||
} | {
|
} | {
|
||||||
results: any[];
|
results: any[];
|
||||||
source?: undefined;
|
source?: undefined;
|
||||||
|
did_you_mean?: undefined;
|
||||||
}>;
|
}>;
|
||||||
reverse(reverseDto: ReverseGeocodeDto): Promise<any>;
|
autocomplete(q: string, country?: string): Promise<{
|
||||||
addPlace(placeData: any): Promise<{
|
results: any;
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
location: string;
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
name_ar: string;
|
|
||||||
name_en: string;
|
|
||||||
address: string;
|
|
||||||
category: string;
|
|
||||||
neighbourhood: string;
|
|
||||||
city: string;
|
|
||||||
description: string;
|
|
||||||
created_at: Date;
|
|
||||||
source: string;
|
source: string;
|
||||||
governorate_id: number;
|
} | {
|
||||||
district_id: number;
|
results: any;
|
||||||
sub_district_id: number;
|
source?: undefined;
|
||||||
neighborhood_id: number;
|
|
||||||
}>;
|
}>;
|
||||||
|
reverse(reverseDto: ReverseGeocodeDto): Promise<any[]>;
|
||||||
|
addPlace(req: any, placeData: any): Promise<import("./entities/map-candidate.entity").MapCandidate>;
|
||||||
deletePlace(country: string, name?: string, id?: string): Promise<{
|
deletePlace(country: string, name?: string, id?: string): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
affected: number | null | undefined;
|
affected: any;
|
||||||
}>;
|
}>;
|
||||||
upsertPlace(placeData: any): Promise<{
|
upsertPlace(placeData: any): Promise<{
|
||||||
id: any;
|
id: any;
|
||||||
@@ -54,7 +50,7 @@ export declare class GeocodingController {
|
|||||||
created: number;
|
created: number;
|
||||||
updated: number;
|
updated: number;
|
||||||
}>;
|
}>;
|
||||||
getPlaces(limit?: string): Promise<(import("./entities/place-syria.entity").PlaceSyria | import("./entities/place-jordan.entity").PlaceJordan | import("./entities/place-egypt.entity").PlaceEgypt)[]>;
|
getPlaces(limit?: string): Promise<any[]>;
|
||||||
getGeoJSON(): Promise<{
|
getGeoJSON(): Promise<{
|
||||||
type: string;
|
type: string;
|
||||||
features: any;
|
features: any;
|
||||||
@@ -72,7 +68,7 @@ export declare class GeocodingController {
|
|||||||
osm: any;
|
osm: any;
|
||||||
overture: any;
|
overture: any;
|
||||||
wikidata: any;
|
wikidata: any;
|
||||||
static_files: {};
|
static_files: any;
|
||||||
hdx: string;
|
hdx: string;
|
||||||
gadm: string;
|
gadm: string;
|
||||||
};
|
};
|
||||||
|
|||||||
+37
-7
@@ -19,7 +19,9 @@ const geocoding_service_1 = require("./geocoding.service");
|
|||||||
const admin_boundaries_service_1 = require("./admin-boundaries.service");
|
const admin_boundaries_service_1 = require("./admin-boundaries.service");
|
||||||
const jordan_research_service_1 = require("./jordan-research.service");
|
const jordan_research_service_1 = require("./jordan-research.service");
|
||||||
const administrative_linking_service_1 = require("./administrative-linking.service");
|
const administrative_linking_service_1 = require("./administrative-linking.service");
|
||||||
|
const map_refinement_service_1 = require("./map-refinement.service");
|
||||||
const api_key_guard_1 = require("../common/guards/api-key.guard");
|
const api_key_guard_1 = require("../common/guards/api-key.guard");
|
||||||
|
const admin_guard_1 = require("../common/guards/admin.guard");
|
||||||
const rate_limiter_guard_1 = require("../common/guards/rate-limiter.guard");
|
const rate_limiter_guard_1 = require("../common/guards/rate-limiter.guard");
|
||||||
const search_query_dto_1 = require("./dto/search-query.dto");
|
const search_query_dto_1 = require("./dto/search-query.dto");
|
||||||
const reverse_geocode_dto_1 = require("./dto/reverse-geocode.dto");
|
const reverse_geocode_dto_1 = require("./dto/reverse-geocode.dto");
|
||||||
@@ -28,22 +30,30 @@ let GeocodingController = class GeocodingController {
|
|||||||
adminBoundariesService;
|
adminBoundariesService;
|
||||||
jordanResearchService;
|
jordanResearchService;
|
||||||
adminLinkingService;
|
adminLinkingService;
|
||||||
constructor(geocodingService, adminBoundariesService, jordanResearchService, adminLinkingService) {
|
refinementService;
|
||||||
|
constructor(geocodingService, adminBoundariesService, jordanResearchService, adminLinkingService, refinementService) {
|
||||||
this.geocodingService = geocodingService;
|
this.geocodingService = geocodingService;
|
||||||
this.adminBoundariesService = adminBoundariesService;
|
this.adminBoundariesService = adminBoundariesService;
|
||||||
this.jordanResearchService = jordanResearchService;
|
this.jordanResearchService = jordanResearchService;
|
||||||
this.adminLinkingService = adminLinkingService;
|
this.adminLinkingService = adminLinkingService;
|
||||||
|
this.refinementService = refinementService;
|
||||||
}
|
}
|
||||||
async search(queryDto) {
|
async search(queryDto) {
|
||||||
const { q, lat, lng, radius, country } = queryDto;
|
const { q, lat, lng, radius, country } = queryDto;
|
||||||
return this.geocodingService.searchPlaces(q, lat, lng, radius, country);
|
return this.geocodingService.searchPlaces(q, lat, lng, radius, country);
|
||||||
}
|
}
|
||||||
|
async autocomplete(q, country) {
|
||||||
|
if (!q || q.trim().length < 2)
|
||||||
|
return { results: [] };
|
||||||
|
return this.geocodingService.autocomplete(q, country);
|
||||||
|
}
|
||||||
async reverse(reverseDto) {
|
async reverse(reverseDto) {
|
||||||
const { lat, lng } = reverseDto;
|
const { lat, lng } = reverseDto;
|
||||||
return this.geocodingService.reverseGeocode(lat, lng);
|
return this.geocodingService.reverseGeocode(lat, lng);
|
||||||
}
|
}
|
||||||
async addPlace(placeData) {
|
async addPlace(req, placeData) {
|
||||||
return this.geocodingService.addPlace(placeData);
|
const userId = req.user?.uid || req.tenant?.id || 'api_key_user';
|
||||||
|
return this.refinementService.suggestPlace(placeData, userId);
|
||||||
}
|
}
|
||||||
async deletePlace(country, name, id) {
|
async deletePlace(country, name, id) {
|
||||||
if (id) {
|
if (id) {
|
||||||
@@ -91,6 +101,17 @@ __decorate([
|
|||||||
__metadata("design:paramtypes", [search_query_dto_1.SearchQueryDto]),
|
__metadata("design:paramtypes", [search_query_dto_1.SearchQueryDto]),
|
||||||
__metadata("design:returntype", Promise)
|
__metadata("design:returntype", Promise)
|
||||||
], GeocodingController.prototype, "search", null);
|
], GeocodingController.prototype, "search", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Get)('autocomplete'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Fast autocomplete for live typing' }),
|
||||||
|
(0, swagger_1.ApiQuery)({ name: 'q', required: true }),
|
||||||
|
(0, swagger_1.ApiQuery)({ name: 'country', required: false }),
|
||||||
|
__param(0, (0, common_1.Query)('q')),
|
||||||
|
__param(1, (0, common_1.Query)('country')),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [String, String]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], GeocodingController.prototype, "autocomplete", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Get)('reverse'),
|
(0, common_1.Get)('reverse'),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Reverse Geocoding (Lat/Lng to Address)' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Reverse Geocoding (Lat/Lng to Address)' }),
|
||||||
@@ -101,14 +122,16 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "reverse", null);
|
], GeocodingController.prototype, "reverse", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('places'),
|
(0, common_1.Post)('places'),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Add a new location (User Submitted)' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Add a new location (User Submitted - Goes to Audit)' }),
|
||||||
__param(0, (0, common_1.Body)()),
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__param(1, (0, common_1.Body)()),
|
||||||
__metadata("design:type", Function),
|
__metadata("design:type", Function),
|
||||||
__metadata("design:paramtypes", [Object]),
|
__metadata("design:paramtypes", [Object, Object]),
|
||||||
__metadata("design:returntype", Promise)
|
__metadata("design:returntype", Promise)
|
||||||
], GeocodingController.prototype, "addPlace", null);
|
], GeocodingController.prototype, "addPlace", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Delete)('places'),
|
(0, common_1.Delete)('places'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Delete a place by name or ID' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Delete a place by name or ID' }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'name', required: false }),
|
(0, swagger_1.ApiQuery)({ name: 'name', required: false }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'id', required: false, type: Number }),
|
(0, swagger_1.ApiQuery)({ name: 'id', required: false, type: Number }),
|
||||||
@@ -122,6 +145,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "deletePlace", null);
|
], GeocodingController.prototype, "deletePlace", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('upsert-place'),
|
(0, common_1.Post)('upsert-place'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Add or Update a location (Automated Scraper)' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Add or Update a location (Automated Scraper)' }),
|
||||||
__param(0, (0, common_1.Body)()),
|
__param(0, (0, common_1.Body)()),
|
||||||
__metadata("design:type", Function),
|
__metadata("design:type", Function),
|
||||||
@@ -130,6 +154,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "upsertPlace", null);
|
], GeocodingController.prototype, "upsertPlace", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('upsert-batch'),
|
(0, common_1.Post)('upsert-batch'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Add or Update multiple locations in bulk' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Add or Update multiple locations in bulk' }),
|
||||||
__param(0, (0, common_1.Body)()),
|
__param(0, (0, common_1.Body)()),
|
||||||
__metadata("design:type", Function),
|
__metadata("design:type", Function),
|
||||||
@@ -153,6 +178,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "getGeoJSON", null);
|
], GeocodingController.prototype, "getGeoJSON", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('import-boundaries'),
|
(0, common_1.Post)('import-boundaries'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Import administrative boundaries from a local GeoJSON file on the server' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Import administrative boundaries from a local GeoJSON file on the server' }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'country', required: true }),
|
(0, swagger_1.ApiQuery)({ name: 'country', required: true }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'filePath', required: true }),
|
(0, swagger_1.ApiQuery)({ name: 'filePath', required: true }),
|
||||||
@@ -171,6 +197,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "zarqaResearch", null);
|
], GeocodingController.prototype, "zarqaResearch", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('admin/sync-neighborhoods'),
|
(0, common_1.Post)('admin/sync-neighborhoods'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Sync neighborhood points from OSM for a bbox' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Sync neighborhood points from OSM for a bbox' }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'bbox', required: false }),
|
(0, swagger_1.ApiQuery)({ name: 'bbox', required: false }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'country', required: false, enum: ['jordan', 'syria', 'egypt'] }),
|
(0, swagger_1.ApiQuery)({ name: 'country', required: false, enum: ['jordan', 'syria', 'egypt'] }),
|
||||||
@@ -182,6 +209,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "syncNeighborhoods", null);
|
], GeocodingController.prototype, "syncNeighborhoods", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('admin/generate-voronoi'),
|
(0, common_1.Post)('admin/generate-voronoi'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Generate Voronoi polygons for neighborhoods' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Generate Voronoi polygons for neighborhoods' }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'country', required: false, enum: ['jordan', 'syria', 'egypt'] }),
|
(0, swagger_1.ApiQuery)({ name: 'country', required: false, enum: ['jordan', 'syria', 'egypt'] }),
|
||||||
__param(0, (0, common_1.Query)('country')),
|
__param(0, (0, common_1.Query)('country')),
|
||||||
@@ -191,6 +219,7 @@ __decorate([
|
|||||||
], GeocodingController.prototype, "generateVoronoi", null);
|
], GeocodingController.prototype, "generateVoronoi", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Post)('admin/link-places'),
|
(0, common_1.Post)('admin/link-places'),
|
||||||
|
(0, common_1.UseGuards)(admin_guard_1.AdminGuard),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Link places to administrative hierarchy' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Link places to administrative hierarchy' }),
|
||||||
(0, swagger_1.ApiQuery)({ name: 'country', required: true, enum: ['jordan', 'syria', 'egypt'] }),
|
(0, swagger_1.ApiQuery)({ name: 'country', required: true, enum: ['jordan', 'syria', 'egypt'] }),
|
||||||
__param(0, (0, common_1.Query)('country')),
|
__param(0, (0, common_1.Query)('country')),
|
||||||
@@ -206,6 +235,7 @@ exports.GeocodingController = GeocodingController = __decorate([
|
|||||||
__metadata("design:paramtypes", [geocoding_service_1.GeocodingService,
|
__metadata("design:paramtypes", [geocoding_service_1.GeocodingService,
|
||||||
admin_boundaries_service_1.AdminBoundariesService,
|
admin_boundaries_service_1.AdminBoundariesService,
|
||||||
jordan_research_service_1.JordanResearchService,
|
jordan_research_service_1.JordanResearchService,
|
||||||
administrative_linking_service_1.AdministrativeLinkingService])
|
administrative_linking_service_1.AdministrativeLinkingService,
|
||||||
|
map_refinement_service_1.MapRefinementService])
|
||||||
], GeocodingController);
|
], GeocodingController);
|
||||||
//# sourceMappingURL=geocoding.controller.js.map
|
//# sourceMappingURL=geocoding.controller.js.map
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
+11
-4
@@ -56,8 +56,12 @@ const jordan_research_service_1 = require("./jordan-research.service");
|
|||||||
const administrative_linking_service_1 = require("./administrative-linking.service");
|
const administrative_linking_service_1 = require("./administrative-linking.service");
|
||||||
const neighborhood_point_entity_1 = require("./entities/neighborhood-point.entity");
|
const neighborhood_point_entity_1 = require("./entities/neighborhood-point.entity");
|
||||||
const neighborhood_polygon_entity_1 = require("./entities/neighborhood-polygon.entity");
|
const neighborhood_polygon_entity_1 = require("./entities/neighborhood-polygon.entity");
|
||||||
|
const map_candidate_entity_1 = require("./entities/map-candidate.entity");
|
||||||
|
const map_refinement_service_1 = require("./map-refinement.service");
|
||||||
|
const map_refinement_controller_1 = require("./map-refinement.controller");
|
||||||
const cache_manager_1 = require("@nestjs/cache-manager");
|
const cache_manager_1 = require("@nestjs/cache-manager");
|
||||||
const redisStore = __importStar(require("cache-manager-redis-store"));
|
const redisStore = __importStar(require("cache-manager-redis-store"));
|
||||||
|
const index_refresh_service_1 = require("./index-refresh.service");
|
||||||
let GeocodingModule = class GeocodingModule {
|
let GeocodingModule = class GeocodingModule {
|
||||||
};
|
};
|
||||||
exports.GeocodingModule = GeocodingModule;
|
exports.GeocodingModule = GeocodingModule;
|
||||||
@@ -72,7 +76,8 @@ exports.GeocodingModule = GeocodingModule = __decorate([
|
|||||||
osm_point_with_area_entity_1.OsmPointWithArea,
|
osm_point_with_area_entity_1.OsmPointWithArea,
|
||||||
admin_boundary_entity_1.AdminBoundary,
|
admin_boundary_entity_1.AdminBoundary,
|
||||||
neighborhood_point_entity_1.NeighborhoodPoint,
|
neighborhood_point_entity_1.NeighborhoodPoint,
|
||||||
neighborhood_polygon_entity_1.NeighborhoodPolygon
|
neighborhood_polygon_entity_1.NeighborhoodPolygon,
|
||||||
|
map_candidate_entity_1.MapCandidate
|
||||||
]),
|
]),
|
||||||
cache_manager_1.CacheModule.register({
|
cache_manager_1.CacheModule.register({
|
||||||
store: redisStore,
|
store: redisStore,
|
||||||
@@ -81,15 +86,17 @@ exports.GeocodingModule = GeocodingModule = __decorate([
|
|||||||
ttl: 3600,
|
ttl: 3600,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
controllers: [geocoding_controller_1.GeocodingController],
|
controllers: [geocoding_controller_1.GeocodingController, map_refinement_controller_1.MapRefinementController],
|
||||||
providers: [
|
providers: [
|
||||||
geocoding_service_1.GeocodingService,
|
geocoding_service_1.GeocodingService,
|
||||||
geocoding_init_service_1.GeocodingInitService,
|
geocoding_init_service_1.GeocodingInitService,
|
||||||
admin_boundaries_service_1.AdminBoundariesService,
|
admin_boundaries_service_1.AdminBoundariesService,
|
||||||
jordan_research_service_1.JordanResearchService,
|
jordan_research_service_1.JordanResearchService,
|
||||||
administrative_linking_service_1.AdministrativeLinkingService
|
administrative_linking_service_1.AdministrativeLinkingService,
|
||||||
|
map_refinement_service_1.MapRefinementService,
|
||||||
|
index_refresh_service_1.IndexRefreshService
|
||||||
],
|
],
|
||||||
exports: [geocoding_service_1.GeocodingService],
|
exports: [geocoding_service_1.GeocodingService, map_refinement_service_1.MapRefinementService],
|
||||||
})
|
})
|
||||||
], GeocodingModule);
|
], GeocodingModule);
|
||||||
//# sourceMappingURL=geocoding.module.js.map
|
//# sourceMappingURL=geocoding.module.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"geocoding.module.js","sourceRoot":"","sources":["../../src/geocoding/geocoding.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAwC;AACxC,6CAAgD;AAChD,2DAAuD;AACvD,qEAAgE;AAChE,iEAA6D;AAC7D,sEAA2D;AAC3D,wEAA6D;AAC7D,sEAA2D;AAC3D,gEAAqD;AACrD,sFAAyE;AACzE,4EAAiE;AACjE,yEAAoE;AACpE,uEAAkE;AAClE,qFAAgF;AAChF,oFAAyE;AACzE,wFAA6E;AAC7E,yDAAoD;AACpD,sEAAwD;AA+BjD,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IA7B3B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC;gBACvB,+BAAU;gBACV,iCAAW;gBACX,+BAAU;gBACV,yBAAO;gBACP,6CAAgB;gBAChB,qCAAa;gBACb,6CAAiB;gBACjB,iDAAmB;aACpB,CAAC;YACF,2BAAW,CAAC,QAAQ,CAAC;gBACnB,KAAK,EAAE,UAAU;gBACjB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW;gBAC3C,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC;gBACpD,GAAG,EAAE,IAAI;aACV,CAAC;SACH;QACD,WAAW,EAAE,CAAC,0CAAmB,CAAC;QAClC,SAAS,EAAE;YACT,oCAAgB;YAChB,6CAAoB;YACpB,iDAAsB;YACtB,+CAAqB;YACrB,6DAA4B;SAC7B;QACD,OAAO,EAAE,CAAC,oCAAgB,CAAC;KAC5B,CAAC;GACW,eAAe,CAAG"}
|
{"version":3,"file":"geocoding.module.js","sourceRoot":"","sources":["../../src/geocoding/geocoding.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAwC;AACxC,6CAAgD;AAChD,2DAAuD;AACvD,qEAAgE;AAChE,iEAA6D;AAC7D,sEAA2D;AAC3D,wEAA6D;AAC7D,sEAA2D;AAC3D,gEAAqD;AACrD,sFAAyE;AACzE,4EAAiE;AACjE,yEAAoE;AACpE,uEAAkE;AAClE,qFAAgF;AAChF,oFAAyE;AACzE,wFAA6E;AAC7E,0EAA+D;AAC/D,qEAAgE;AAChE,2EAAsE;AACtE,yDAAoD;AACpD,sEAAwD;AACxD,mEAA8D;AAkCvD,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IAhC3B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,uBAAa,CAAC,UAAU,CAAC;gBACvB,+BAAU;gBACV,iCAAW;gBACX,+BAAU;gBACV,yBAAO;gBACP,6CAAgB;gBAChB,qCAAa;gBACb,6CAAiB;gBACjB,iDAAmB;gBACnB,mCAAY;aACb,CAAC;YACF,2BAAW,CAAC,QAAQ,CAAC;gBACnB,KAAK,EAAE,UAAU;gBACjB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW;gBAC3C,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,MAAM,EAAE,EAAE,CAAC;gBACpD,GAAG,EAAE,IAAI;aACV,CAAC;SACH;QACD,WAAW,EAAE,CAAC,0CAAmB,EAAE,mDAAuB,CAAC;QAC3D,SAAS,EAAE;YACT,oCAAgB;YAChB,6CAAoB;YACpB,iDAAsB;YACtB,+CAAqB;YACrB,6DAA4B;YAC5B,6CAAoB;YACpB,2CAAmB;SACpB;QACD,OAAO,EAAE,CAAC,oCAAgB,EAAE,6CAAoB,CAAC;KAClD,CAAC;GACW,eAAe,CAAG"}
|
||||||
+17
-22
@@ -22,33 +22,28 @@ export declare class GeocodingService {
|
|||||||
searchPlaces(query: string, lat?: number, lon?: number, radius?: number, country?: string): Promise<{
|
searchPlaces(query: string, lat?: number, lon?: number, radius?: number, country?: string): Promise<{
|
||||||
results: any;
|
results: any;
|
||||||
source: string;
|
source: string;
|
||||||
|
did_you_mean?: undefined;
|
||||||
|
} | {
|
||||||
|
results: never[];
|
||||||
|
did_you_mean: any;
|
||||||
|
source?: undefined;
|
||||||
} | {
|
} | {
|
||||||
results: any[];
|
results: any[];
|
||||||
source?: undefined;
|
source?: undefined;
|
||||||
|
did_you_mean?: undefined;
|
||||||
}>;
|
}>;
|
||||||
private formatResults;
|
private formatResults;
|
||||||
private getRepoByTableName;
|
private getRepoByTableName;
|
||||||
reverseGeocode(lat: number, lng: number): Promise<any>;
|
private logFailedSearch;
|
||||||
addPlace(data: Partial<BasePlace>): Promise<{
|
autocomplete(query: string, country?: string): Promise<{
|
||||||
latitude: number;
|
results: any;
|
||||||
longitude: number;
|
|
||||||
location: string;
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
name_ar: string;
|
|
||||||
name_en: string;
|
|
||||||
address: string;
|
|
||||||
category: string;
|
|
||||||
neighbourhood: string;
|
|
||||||
city: string;
|
|
||||||
description: string;
|
|
||||||
created_at: Date;
|
|
||||||
source: string;
|
source: string;
|
||||||
governorate_id: number;
|
} | {
|
||||||
district_id: number;
|
results: any;
|
||||||
sub_district_id: number;
|
source?: undefined;
|
||||||
neighborhood_id: number;
|
|
||||||
}>;
|
}>;
|
||||||
|
reverseGeocode(lat: number, lng: number): Promise<any[]>;
|
||||||
|
addPlace(data: Partial<BasePlace>): Promise<any>;
|
||||||
upsertPlace(data: Partial<BasePlace>): Promise<{
|
upsertPlace(data: Partial<BasePlace>): Promise<{
|
||||||
id: any;
|
id: any;
|
||||||
action: string;
|
action: string;
|
||||||
@@ -59,18 +54,18 @@ export declare class GeocodingService {
|
|||||||
created: number;
|
created: number;
|
||||||
updated: number;
|
updated: number;
|
||||||
}>;
|
}>;
|
||||||
getRecentPlaces(limit?: number): Promise<(PlaceSyria | PlaceJordan | PlaceEgypt)[]>;
|
getRecentPlaces(limit?: number): Promise<any[]>;
|
||||||
getAllPlacesGeoJSON(): Promise<{
|
getAllPlacesGeoJSON(): Promise<{
|
||||||
type: string;
|
type: string;
|
||||||
features: any;
|
features: any;
|
||||||
}>;
|
}>;
|
||||||
deletePlacesByName(name: string, country: string): Promise<{
|
deletePlacesByName(name: string, country: string): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
affected: number;
|
affected: any;
|
||||||
}>;
|
}>;
|
||||||
deletePlaceById(id: number, country: string): Promise<{
|
deletePlaceById(id: number, country: string): Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
affected: number | null | undefined;
|
affected: any;
|
||||||
}>;
|
}>;
|
||||||
private getRepoByCountry;
|
private getRepoByCountry;
|
||||||
}
|
}
|
||||||
|
|||||||
+239
-51
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||||||
return function (target, key) { decorator(target, key, paramIndex); }
|
return function (target, key) { decorator(target, key, paramIndex); }
|
||||||
};
|
};
|
||||||
var GeocodingService_1;
|
var GeocodingService_1;
|
||||||
|
var _a, _b, _c, _d, _e;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.GeocodingService = void 0;
|
exports.GeocodingService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -73,9 +74,16 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
}
|
}
|
||||||
async searchPlaces(query, lat, lon, radius = 20000, country) {
|
async searchPlaces(query, lat, lon, radius = 20000, country) {
|
||||||
try {
|
try {
|
||||||
const cleanQuery = query.trim();
|
let cleanQuery = query.trim();
|
||||||
if (!cleanQuery)
|
if (!cleanQuery)
|
||||||
return { results: [] };
|
return { results: [] };
|
||||||
|
let relativePrefix = '';
|
||||||
|
const relativeQueryRegex = /^(قرب|بالقرب من|قريب من|عند|بجانب|جنب|حد|بجوار|مقابل|قبال|خلف|ورا|وراء)\s+(.+)$/i;
|
||||||
|
const match = cleanQuery.match(relativeQueryRegex);
|
||||||
|
if (match) {
|
||||||
|
relativePrefix = match[1];
|
||||||
|
cleanQuery = match[2];
|
||||||
|
}
|
||||||
const hasLocation = lat !== undefined && lon !== undefined;
|
const hasLocation = lat !== undefined && lon !== undefined;
|
||||||
const geoSegment = hasLocation ? `${lat.toFixed(2)}_${lon.toFixed(2)}` : 'global';
|
const geoSegment = hasLocation ? `${lat.toFixed(2)}_${lon.toFixed(2)}` : 'global';
|
||||||
const cacheKey = `geo_search:${country || 'auto'}:${geoSegment}:${cleanQuery.toLowerCase()}`;
|
const cacheKey = `geo_search:${country || 'auto'}:${geoSegment}:${cleanQuery.toLowerCase()}`;
|
||||||
@@ -83,56 +91,93 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
if (cached)
|
if (cached)
|
||||||
return { results: cached, source: 'cache_hit' };
|
return { results: cached, source: 'cache_hit' };
|
||||||
let targetRegion = country?.toLowerCase() || this.identifyRegion(lat, lon);
|
let targetRegion = country?.toLowerCase() || this.identifyRegion(lat, lon);
|
||||||
const primaryTables = targetRegion && ['syria', 'egypt', 'jordan'].includes(targetRegion)
|
const [normalizedQueryRes] = await this.osmPointsRepository.query(`SELECT normalize_arabic($1) as nq`, [cleanQuery]);
|
||||||
? [`places_${targetRegion}`] : ['places_jordan', 'places_syria', 'places_egypt'];
|
const normalizedQuery = normalizedQueryRes?.nq || cleanQuery.toLowerCase();
|
||||||
const queryPromises = [];
|
let queryParams = [normalizedQuery];
|
||||||
primaryTables.forEach(tableName => {
|
let locationCondition = '';
|
||||||
const repo = this.getRepoByTableName(tableName);
|
if (hasLocation) {
|
||||||
queryPromises.push(repo.query(`
|
locationCondition = `AND ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) <= $4`;
|
||||||
|
queryParams.push(lat, lon, radius);
|
||||||
|
}
|
||||||
|
let regionCondition = '';
|
||||||
|
if (targetRegion && ['syria', 'jordan', 'egypt'].includes(targetRegion)) {
|
||||||
|
regionCondition = `AND (region = '${targetRegion}' OR region = 'global')`;
|
||||||
|
}
|
||||||
|
const sqlQuery = `
|
||||||
SELECT
|
SELECT
|
||||||
p.id, p.name, p.name_ar, p.name_en, p.category,
|
id, name, name_ar, category,
|
||||||
n.name_ar as neighbourhood, d.name_ar as district, g.name_ar as governorate,
|
'' as neighbourhood, '' as district, '' as governorate,
|
||||||
p.latitude, p.longitude, p.address, '${tableName.replace('places_', '')}' as region, 'user_place' as source,
|
latitude, longitude, address, region, source, popularity_score,
|
||||||
CASE WHEN $2::float IS NOT NULL THEN ST_DistanceSphere(p.location, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) ELSE 0 END as distance,
|
${hasLocation ? 'ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326))' : '0'} as distance,
|
||||||
GREATEST(similarity(COALESCE(p.name_ar, ''), $1), similarity(COALESCE(p.name, ''), $1)) as relevance
|
similarity(normalized_name, $1) as relevance
|
||||||
FROM ${tableName} p
|
FROM unified_search_index
|
||||||
LEFT JOIN neighborhood_polygons n ON p.neighborhood_id = n.id
|
WHERE normalized_name % $1
|
||||||
LEFT JOIN admin_boundaries d ON p.district_id = d.id
|
${locationCondition}
|
||||||
LEFT JOIN admin_boundaries g ON p.governorate_id = g.id
|
${regionCondition}
|
||||||
WHERE (p.name_ar % $1 OR p.name % $1)
|
ORDER BY (normalized_name <-> $1) ASC
|
||||||
AND ($2::float IS NULL OR ST_DistanceSphere(p.location, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) <= $4)
|
LIMIT 50
|
||||||
ORDER BY (p.name_ar <-> $1) ASC LIMIT 10
|
`;
|
||||||
`, [cleanQuery, lat || null, lon || null, radius]));
|
const allResults = await Promise.race([
|
||||||
});
|
this.osmPointsRepository.query(sqlQuery, queryParams),
|
||||||
queryPromises.push(this.osmPointsRepository.query(`
|
|
||||||
SELECT
|
|
||||||
o.osm_id as id, o.name, o.name_ar, o.name_en, COALESCE(o.amenity, o.shop, 'place') as category,
|
|
||||||
o.latitude, o.longitude, o.addr_street as address, 'osm_global' as source,
|
|
||||||
CASE WHEN $2::float IS NOT NULL THEN ST_DistanceSphere(o.geom, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) ELSE 0 END as distance,
|
|
||||||
GREATEST(similarity(COALESCE(o.name, ''), $1), similarity(COALESCE(o.name_ar, ''), $1)) as relevance
|
|
||||||
FROM osm_points_with_area o
|
|
||||||
WHERE (o.name % $1 OR o.name_ar % $1)
|
|
||||||
AND ($2::float IS NULL OR ST_DistanceSphere(o.geom, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) <= $4)
|
|
||||||
ORDER BY (o.name <-> $1) ASC LIMIT 10
|
|
||||||
`, [cleanQuery, lat || null, lon || null, radius]));
|
|
||||||
const executionResults = await Promise.race([
|
|
||||||
Promise.allSettled(queryPromises),
|
|
||||||
new Promise((_, reject) => setTimeout(() => reject(new Error('QUERY_TIMEOUT')), this.DB_TIMEOUT_MS))
|
new Promise((_, reject) => setTimeout(() => reject(new Error('QUERY_TIMEOUT')), this.DB_TIMEOUT_MS))
|
||||||
]).catch(e => {
|
]).catch(e => {
|
||||||
this.logger.warn(`Search optimization threshold hit: ${e.message}`);
|
this.logger.warn(`Search optimization threshold hit: ${e.message}`);
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
let allResults = [];
|
const formatted = this.formatResults(allResults, hasLocation, relativePrefix);
|
||||||
if (Array.isArray(executionResults)) {
|
const placeIds = formatted.map(r => r.id);
|
||||||
executionResults.forEach(res => {
|
if (placeIds.length > 0) {
|
||||||
if (res.status === 'fulfilled' && res.value)
|
try {
|
||||||
allResults.push(...res.value);
|
const gates = await this.osmPointsRepository.query(`SELECT place_id, gate_name_ar, gate_name_en, latitude, longitude, is_main_gate
|
||||||
|
FROM place_gates
|
||||||
|
WHERE place_id = ANY($1)`, [placeIds]);
|
||||||
|
if (gates.length > 0) {
|
||||||
|
formatted.forEach(r => {
|
||||||
|
const placeGates = gates.filter((g) => g.place_id === r.id).map((g) => ({
|
||||||
|
name_ar: g.gate_name_ar,
|
||||||
|
name_en: g.gate_name_en,
|
||||||
|
latitude: parseFloat(g.latitude),
|
||||||
|
longitude: parseFloat(g.longitude),
|
||||||
|
is_main_gate: g.is_main_gate
|
||||||
|
}));
|
||||||
|
if (placeGates.length > 0) {
|
||||||
|
r.gates = placeGates;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const formatted = this.formatResults(allResults, hasLocation);
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.logger.warn('Failed to fetch POI gates, table might not exist yet.');
|
||||||
|
}
|
||||||
|
}
|
||||||
if (formatted.length > 0) {
|
if (formatted.length > 0) {
|
||||||
await this.cacheManager.set(cacheKey, formatted, 3600000);
|
await this.cacheManager.set(cacheKey, formatted, 3600000);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this.logFailedSearch(cleanQuery, normalizedQuery, targetRegion, lat, lon).catch(err => {
|
||||||
|
this.logger.error('Failed to log zero-result search:', err);
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const whereClause = regionCondition ? `WHERE ${regionCondition.substring(4)}` : '';
|
||||||
|
const fallbackQuery = `
|
||||||
|
SELECT name_ar, name, (normalized_name <-> $1) as dist
|
||||||
|
FROM unified_search_index
|
||||||
|
${whereClause}
|
||||||
|
ORDER BY normalized_name <-> $1 ASC
|
||||||
|
LIMIT 1
|
||||||
|
`;
|
||||||
|
const suggestions = await this.osmPointsRepository.query(fallbackQuery, [normalizedQuery]);
|
||||||
|
if (suggestions.length > 0 && suggestions[0].dist < 0.6) {
|
||||||
|
return {
|
||||||
|
results: [],
|
||||||
|
did_you_mean: suggestions[0].name_ar || suggestions[0].name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.logger.warn('Did You Mean fallback failed: ' + err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
return { results: formatted };
|
return { results: formatted };
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@@ -140,12 +185,15 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
return { results: [] };
|
return { results: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formatResults(results, hasLocation) {
|
formatResults(results, hasLocation, relativePrefix = '') {
|
||||||
const seenStreets = new Set();
|
const seenStreets = new Set();
|
||||||
|
const maxPopularity = Math.max(...results.map(r => r.popularity_score || 10), 100);
|
||||||
return results
|
return results
|
||||||
.map(r => {
|
.map(r => {
|
||||||
|
const textScore = Number(r.relevance);
|
||||||
|
const popularityScore = (r.popularity_score || 10) / maxPopularity;
|
||||||
const proximityBonus = hasLocation ? Math.max(0, 1 - (Number(r.distance) / 10000)) : 0;
|
const proximityBonus = hasLocation ? Math.max(0, 1 - (Number(r.distance) / 10000)) : 0;
|
||||||
const totalScore = (Number(r.relevance) * 0.7) + (proximityBonus * 0.3);
|
const totalScore = (textScore * 0.5) + (popularityScore * 0.3) + (proximityBonus * 0.2);
|
||||||
return { ...r, totalScore };
|
return { ...r, totalScore };
|
||||||
})
|
})
|
||||||
.sort((a, b) => b.totalScore - a.totalScore)
|
.sort((a, b) => b.totalScore - a.totalScore)
|
||||||
@@ -162,8 +210,12 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
.map(r => {
|
.map(r => {
|
||||||
const addressParts = [r.neighbourhood, r.district, r.governorate].filter(Boolean);
|
const addressParts = [r.neighbourhood, r.district, r.governorate].filter(Boolean);
|
||||||
const full_address = addressParts.length > 0 ? addressParts.join('، ') : (r.address || '');
|
const full_address = addressParts.length > 0 ? addressParts.join('، ') : (r.address || '');
|
||||||
|
const nameAr = r.name_ar || r.name;
|
||||||
|
const displayName = relativePrefix ? `${relativePrefix} ${nameAr}` : nameAr;
|
||||||
return {
|
return {
|
||||||
...r,
|
...r,
|
||||||
|
name: displayName,
|
||||||
|
name_ar: displayName,
|
||||||
latitude: parseFloat(r.latitude),
|
latitude: parseFloat(r.latitude),
|
||||||
longitude: parseFloat(r.longitude),
|
longitude: parseFloat(r.longitude),
|
||||||
distance_km: r.distance ? (Number(r.distance) / 1000).toFixed(2) : null,
|
distance_km: r.distance ? (Number(r.distance) / 1000).toFixed(2) : null,
|
||||||
@@ -179,11 +231,78 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
return this.placesJordanRepository;
|
return this.placesJordanRepository;
|
||||||
return this.placesSyriaRepository;
|
return this.placesSyriaRepository;
|
||||||
}
|
}
|
||||||
|
async logFailedSearch(query, normalizedQuery, country, lat, lon) {
|
||||||
|
const q = `
|
||||||
|
INSERT INTO failed_searches (query_text, normalized_query, country, latitude, longitude)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
ON CONFLICT (normalized_query, COALESCE(country, 'global'))
|
||||||
|
DO UPDATE SET search_count = failed_searches.search_count + 1, last_seen_at = CURRENT_TIMESTAMP;
|
||||||
|
`;
|
||||||
|
await this.osmPointsRepository.query(q, [query, normalizedQuery, country || null, lat || null, lon || null]);
|
||||||
|
}
|
||||||
|
async autocomplete(query, country) {
|
||||||
|
try {
|
||||||
|
let cleanQuery = query.trim();
|
||||||
|
if (cleanQuery.length < 2)
|
||||||
|
return { results: [] };
|
||||||
|
let relativePrefix = '';
|
||||||
|
const relativeQueryRegex = /^(قرب|بالقرب من|قريب من|عند|بجانب|جنب|حد|بجوار|مقابل|قبال|خلف|ورا|وراء)\s+(.+)$/i;
|
||||||
|
const match = cleanQuery.match(relativeQueryRegex);
|
||||||
|
if (match) {
|
||||||
|
relativePrefix = match[1];
|
||||||
|
cleanQuery = match[2];
|
||||||
|
if (cleanQuery.length < 2)
|
||||||
|
return { results: [] };
|
||||||
|
}
|
||||||
|
const targetRegion = country?.toLowerCase();
|
||||||
|
const cacheKey = `geo_auto:${targetRegion || 'auto'}:${cleanQuery.toLowerCase()}`;
|
||||||
|
const cached = await this.cacheManager.get(cacheKey);
|
||||||
|
if (cached)
|
||||||
|
return { results: cached, source: 'cache_hit' };
|
||||||
|
const [normalizedQueryRes] = await this.osmPointsRepository.query(`SELECT normalize_arabic($1) as nq`, [cleanQuery]);
|
||||||
|
const normalizedQuery = normalizedQueryRes?.nq || cleanQuery.toLowerCase();
|
||||||
|
let queryParams = [`${normalizedQuery}%`];
|
||||||
|
let regionCondition = '';
|
||||||
|
if (targetRegion && ['syria', 'jordan', 'egypt'].includes(targetRegion)) {
|
||||||
|
regionCondition = `AND (region = '${targetRegion}' OR region = 'global')`;
|
||||||
|
}
|
||||||
|
const sqlQuery = `
|
||||||
|
SELECT
|
||||||
|
id, name, name_ar, category, region, source, address
|
||||||
|
FROM unified_search_index
|
||||||
|
WHERE normalized_name LIKE $1
|
||||||
|
${regionCondition}
|
||||||
|
ORDER BY LENGTH(normalized_name) ASC
|
||||||
|
LIMIT 7
|
||||||
|
`;
|
||||||
|
const results = await this.osmPointsRepository.query(sqlQuery, queryParams);
|
||||||
|
const formatted = results.map(r => {
|
||||||
|
const nameAr = r.name_ar || r.name;
|
||||||
|
const displayName = relativePrefix ? `${relativePrefix} ${nameAr}` : nameAr;
|
||||||
|
return {
|
||||||
|
id: r.id,
|
||||||
|
name: displayName,
|
||||||
|
category: r.category,
|
||||||
|
region: r.region,
|
||||||
|
address: r.address
|
||||||
|
};
|
||||||
|
});
|
||||||
|
if (formatted.length > 0) {
|
||||||
|
await this.cacheManager.set(cacheKey, formatted, 3600000);
|
||||||
|
}
|
||||||
|
return { results: formatted };
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.logger.error('Autocomplete failed:', e);
|
||||||
|
return { results: [] };
|
||||||
|
}
|
||||||
|
}
|
||||||
async reverseGeocode(lat, lng) {
|
async reverseGeocode(lat, lng) {
|
||||||
try {
|
try {
|
||||||
const repo = this.getRepositoryForCoords(lat, lng);
|
const repo = this.getRepositoryForCoords(lat, lng);
|
||||||
const tableName = this.getTableNameForRepo(repo);
|
const tableName = this.getTableNameForRepo(repo);
|
||||||
const query = `
|
const queryPromises = [];
|
||||||
|
queryPromises.push(repo.query(`
|
||||||
SELECT
|
SELECT
|
||||||
p.id, p.name, p.name_ar, p.category,
|
p.id, p.name, p.name_ar, p.category,
|
||||||
n.name_ar as neighbourhood,
|
n.name_ar as neighbourhood,
|
||||||
@@ -196,9 +315,81 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
LEFT JOIN admin_boundaries d ON p.sub_district_id = d.id
|
LEFT JOIN admin_boundaries d ON p.sub_district_id = d.id
|
||||||
LEFT JOIN admin_boundaries g ON p.governorate_id = g.id
|
LEFT JOIN admin_boundaries g ON p.governorate_id = g.id
|
||||||
WHERE p.location IS NOT NULL
|
WHERE p.location IS NOT NULL
|
||||||
ORDER BY p.location::geometry <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 3
|
ORDER BY p.location::geometry <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 5
|
||||||
`;
|
`, [lng, lat]));
|
||||||
return await repo.query(query, [lng, lat]);
|
queryPromises.push(repo.query(`
|
||||||
|
SELECT
|
||||||
|
o.osm_id::text as id, o.name, o.name_ar, COALESCE(o.amenity, o.shop, 'place') as category,
|
||||||
|
'' as neighbourhood, '' as district, '' as governorate,
|
||||||
|
o.latitude, o.longitude, o.addr_street as address, 'osm_global' as source,
|
||||||
|
ST_DistanceSphere(o.geom, ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326)) as distance
|
||||||
|
FROM osm_points_with_area o
|
||||||
|
WHERE o.geom IS NOT NULL AND (o.name IS NOT NULL OR o.name_ar IS NOT NULL)
|
||||||
|
ORDER BY o.geom <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 5
|
||||||
|
`, [lng, lat]));
|
||||||
|
queryPromises.push(repo.query(`
|
||||||
|
SELECT
|
||||||
|
id::text, COALESCE(names->>'primary', names->>'common', 'Street') as name, COALESCE(names->>'primary', names->>'common', 'Street') as name_ar, 'street' as category,
|
||||||
|
'' as neighbourhood, '' as district, '' as governorate,
|
||||||
|
ST_Y(ST_Centroid(location))::text as latitude, ST_X(ST_Centroid(location))::text as longitude, '' as address, 'overture_global' as source,
|
||||||
|
ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326)) as distance
|
||||||
|
FROM overture_segment
|
||||||
|
WHERE location IS NOT NULL AND (names->>'primary' IS NOT NULL OR names->>'common' IS NOT NULL)
|
||||||
|
ORDER BY location <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 5
|
||||||
|
`, [lng, lat]));
|
||||||
|
queryPromises.push(repo.query(`
|
||||||
|
SELECT
|
||||||
|
id::text, COALESCE(names->>'primary', names->>'common', 'Building') as name, COALESCE(names->>'primary', names->>'common', 'Building') as name_ar, 'building' as category,
|
||||||
|
'' as neighbourhood, '' as district, '' as governorate,
|
||||||
|
ST_Y(ST_Centroid(location))::text as latitude, ST_X(ST_Centroid(location))::text as longitude, '' as address, 'overture_global' as source,
|
||||||
|
ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326)) as distance
|
||||||
|
FROM overture_building
|
||||||
|
WHERE location IS NOT NULL AND (names->>'primary' IS NOT NULL OR names->>'common' IS NOT NULL)
|
||||||
|
ORDER BY location <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 5
|
||||||
|
`, [lng, lat]));
|
||||||
|
queryPromises.push(repo.query(`
|
||||||
|
SELECT
|
||||||
|
id::text, COALESCE(names->>'primary', names->>'common', 'Place') as name, COALESCE(names->>'primary', names->>'common', 'Place') as name_ar, 'place' as category,
|
||||||
|
'' as neighbourhood, '' as district, '' as governorate,
|
||||||
|
ST_Y(ST_Centroid(location))::text as latitude, ST_X(ST_Centroid(location))::text as longitude, '' as address, 'overture_global' as source,
|
||||||
|
ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326)) as distance
|
||||||
|
FROM overture_place
|
||||||
|
WHERE location IS NOT NULL AND (names->>'primary' IS NOT NULL OR names->>'common' IS NOT NULL)
|
||||||
|
ORDER BY location <-> ST_SetSRID(ST_MakePoint($1::float, $2::float), 4326) ASC LIMIT 5
|
||||||
|
`, [lng, lat]));
|
||||||
|
const results = await Promise.allSettled(queryPromises);
|
||||||
|
let allResults = [];
|
||||||
|
results.forEach(res => {
|
||||||
|
if (res.status === 'fulfilled' && res.value)
|
||||||
|
allResults.push(...res.value);
|
||||||
|
});
|
||||||
|
return allResults
|
||||||
|
.sort((a, b) => Number(a.distance) - Number(b.distance))
|
||||||
|
.slice(0, 5)
|
||||||
|
.map(r => {
|
||||||
|
const distance = Number(r.distance);
|
||||||
|
const fullAddressParts = [r.name_ar || r.name, r.address, r.neighbourhood, r.district, r.governorate].filter(Boolean);
|
||||||
|
let humanReadable = r.name_ar || r.name;
|
||||||
|
if (distance <= 20) {
|
||||||
|
humanReadable = r.name_ar || r.name;
|
||||||
|
}
|
||||||
|
else if (distance <= 70 && r.category !== 'street') {
|
||||||
|
const streetName = r.address ? `، ${r.address}` : '';
|
||||||
|
humanReadable = `أمام ${r.name_ar || r.name}${streetName}`;
|
||||||
|
}
|
||||||
|
else if (r.category === 'street' || distance > 70) {
|
||||||
|
const streetPart = r.category === 'street' ? (r.name_ar || r.name) : (r.address || r.name_ar || r.name);
|
||||||
|
const districtPart = r.neighbourhood || r.district || '';
|
||||||
|
humanReadable = [streetPart, districtPart].filter(Boolean).join('، ');
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...r,
|
||||||
|
latitude: parseFloat(r.latitude),
|
||||||
|
longitude: parseFloat(r.longitude),
|
||||||
|
human_readable_address: humanReadable,
|
||||||
|
full_address: fullAddressParts.join('، ')
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
this.logger.error('Reverse geocoding error:', error);
|
this.logger.error('Reverse geocoding error:', error);
|
||||||
@@ -259,6 +450,7 @@ let GeocodingService = GeocodingService_1 = class GeocodingService {
|
|||||||
UNION ALL SELECT id::text, name_ar as name, category, latitude, longitude, address, 'user' as region FROM places_egypt
|
UNION ALL SELECT id::text, name_ar as name, category, latitude, longitude, address, 'user' as region FROM places_egypt
|
||||||
UNION ALL SELECT id::text, COALESCE(names->>'primary', names->>'common', 'Building') as name, 'building' as category, ST_Y(ST_Centroid(location)) as latitude, ST_X(ST_Centroid(location)) as longitude, '' as address, 'overture' as region FROM overture_building WHERE names->>'primary' IS NOT NULL LIMIT 500
|
UNION ALL SELECT id::text, COALESCE(names->>'primary', names->>'common', 'Building') as name, 'building' as category, ST_Y(ST_Centroid(location)) as latitude, ST_X(ST_Centroid(location)) as longitude, '' as address, 'overture' as region FROM overture_building WHERE names->>'primary' IS NOT NULL LIMIT 500
|
||||||
UNION ALL SELECT id::text, COALESCE(names->>'primary', names->>'common', 'Street') as name, 'street' as category, ST_Y(ST_Centroid(location)) as latitude, ST_X(ST_Centroid(location)) as longitude, '' as address, 'overture' as region FROM overture_segment WHERE names->>'primary' IS NOT NULL LIMIT 500
|
UNION ALL SELECT id::text, COALESCE(names->>'primary', names->>'common', 'Street') as name, 'street' as category, ST_Y(ST_Centroid(location)) as latitude, ST_X(ST_Centroid(location)) as longitude, '' as address, 'overture' as region FROM overture_segment WHERE names->>'primary' IS NOT NULL LIMIT 500
|
||||||
|
UNION ALL SELECT id::text, COALESCE(names->>'primary', names->>'common', 'Place') as name, 'place' as category, ST_Y(ST_Centroid(location)) as latitude, ST_X(ST_Centroid(location)) as longitude, '' as address, 'overture' as region FROM overture_place WHERE names->>'primary' IS NOT NULL LIMIT 500
|
||||||
`;
|
`;
|
||||||
const res = await this.placesSyriaRepository.query(q);
|
const res = await this.placesSyriaRepository.query(q);
|
||||||
const features = res.map(p => ({
|
const features = res.map(p => ({
|
||||||
@@ -299,10 +491,6 @@ exports.GeocodingService = GeocodingService = GeocodingService_1 = __decorate([
|
|||||||
__param(3, (0, typeorm_1.InjectRepository)(osm_area_entity_1.OsmArea)),
|
__param(3, (0, typeorm_1.InjectRepository)(osm_area_entity_1.OsmArea)),
|
||||||
__param(4, (0, typeorm_1.InjectRepository)(osm_point_with_area_entity_1.OsmPointWithArea)),
|
__param(4, (0, typeorm_1.InjectRepository)(osm_point_with_area_entity_1.OsmPointWithArea)),
|
||||||
__param(5, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
__param(5, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, typeof (_c = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _c : Object, typeof (_d = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _d : Object, typeof (_e = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _e : Object, Object])
|
||||||
typeorm_2.Repository,
|
|
||||||
typeorm_2.Repository,
|
|
||||||
typeorm_2.Repository,
|
|
||||||
typeorm_2.Repository, Object])
|
|
||||||
], GeocodingService);
|
], GeocodingService);
|
||||||
//# sourceMappingURL=geocoding.service.js.map
|
//# sourceMappingURL=geocoding.service.js.map
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
|||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { OsmPointWithArea } from './entities/osm-point-with-area.entity';
|
||||||
|
export declare class IndexRefreshService {
|
||||||
|
private readonly repo;
|
||||||
|
private readonly logger;
|
||||||
|
constructor(repo: Repository<OsmPointWithArea>);
|
||||||
|
handleCron(): Promise<void>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
"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 IndexRefreshService_1;
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.IndexRefreshService = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const schedule_1 = require("@nestjs/schedule");
|
||||||
|
const typeorm_1 = require("@nestjs/typeorm");
|
||||||
|
const typeorm_2 = require("typeorm");
|
||||||
|
const osm_point_with_area_entity_1 = require("./entities/osm-point-with-area.entity");
|
||||||
|
let IndexRefreshService = IndexRefreshService_1 = class IndexRefreshService {
|
||||||
|
repo;
|
||||||
|
logger = new common_1.Logger(IndexRefreshService_1.name);
|
||||||
|
constructor(repo) {
|
||||||
|
this.repo = repo;
|
||||||
|
}
|
||||||
|
async handleCron() {
|
||||||
|
this.logger.log('Starting background refresh for unified_search_index...');
|
||||||
|
try {
|
||||||
|
await this.repo.query('REFRESH MATERIALIZED VIEW CONCURRENTLY unified_search_index;');
|
||||||
|
this.logger.log('Successfully refreshed unified_search_index.');
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error('Failed to refresh unified_search_index', error);
|
||||||
|
try {
|
||||||
|
this.logger.log('Attempting standard refresh (blocking)...');
|
||||||
|
await this.repo.query('REFRESH MATERIALIZED VIEW unified_search_index;');
|
||||||
|
this.logger.log('Successfully refreshed unified_search_index (standard).');
|
||||||
|
}
|
||||||
|
catch (fallbackError) {
|
||||||
|
this.logger.error('Fallback standard refresh also failed', fallbackError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.IndexRefreshService = IndexRefreshService;
|
||||||
|
__decorate([
|
||||||
|
(0, schedule_1.Cron)(schedule_1.CronExpression.EVERY_5_MINUTES),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", []),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], IndexRefreshService.prototype, "handleCron", null);
|
||||||
|
exports.IndexRefreshService = IndexRefreshService = IndexRefreshService_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__param(0, (0, typeorm_1.InjectRepository)(osm_point_with_area_entity_1.OsmPointWithArea)),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object])
|
||||||
|
], IndexRefreshService);
|
||||||
|
//# sourceMappingURL=index-refresh.service.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"index-refresh.service.js","sourceRoot":"","sources":["../../src/geocoding/index-refresh.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,+CAAwD;AACxD,6CAAmD;AACnD,qCAAqC;AACrC,sFAAyE;AAGlE,IAAM,mBAAmB,2BAAzB,MAAM,mBAAmB;IAKX;IAJF,MAAM,GAAG,IAAI,eAAM,CAAC,qBAAmB,CAAC,IAAI,CAAC,CAAC;IAE/D,YAEmB,IAAkC;QAAlC,SAAI,GAAJ,IAAI,CAA8B;IAClD,CAAC;IAIE,AAAN,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;QAC3E,IAAI,CAAC;YAEH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;YACtF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;YAGnE,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;gBAC7D,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACzE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YAC7E,CAAC;YAAC,OAAO,aAAa,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,aAAa,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAA;AA7BY,kDAAmB;AAUxB;IADL,IAAA,eAAI,EAAC,yBAAc,CAAC,eAAe,CAAC;;;;qDAmBpC;8BA5BU,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,0BAAgB,EAAC,6CAAgB,CAAC,CAAA;yDACZ,oBAAU,oBAAV,oBAAU;GALxB,mBAAmB,CA6B/B"}
|
||||||
+1
-1
@@ -16,7 +16,7 @@ export declare class JordanResearchService {
|
|||||||
osm: any;
|
osm: any;
|
||||||
overture: any;
|
overture: any;
|
||||||
wikidata: any;
|
wikidata: any;
|
||||||
static_files: {};
|
static_files: any;
|
||||||
hdx: string;
|
hdx: string;
|
||||||
gadm: string;
|
gadm: string;
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -48,6 +48,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
var JordanResearchService_1;
|
var JordanResearchService_1;
|
||||||
|
var _a;
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.JordanResearchService = void 0;
|
exports.JordanResearchService = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
@@ -178,6 +179,6 @@ exports.JordanResearchService = JordanResearchService;
|
|||||||
exports.JordanResearchService = JordanResearchService = JordanResearchService_1 = __decorate([
|
exports.JordanResearchService = JordanResearchService = JordanResearchService_1 = __decorate([
|
||||||
(0, common_1.Injectable)(),
|
(0, common_1.Injectable)(),
|
||||||
__param(0, (0, typeorm_1.InjectRepository)(place_jordan_entity_1.PlaceJordan)),
|
__param(0, (0, typeorm_1.InjectRepository)(place_jordan_entity_1.PlaceJordan)),
|
||||||
__metadata("design:paramtypes", [typeorm_2.Repository])
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object])
|
||||||
], JordanResearchService);
|
], JordanResearchService);
|
||||||
//# sourceMappingURL=jordan-research.service.js.map
|
//# sourceMappingURL=jordan-research.service.js.map
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"jordan-research.service.js","sourceRoot":"","sources":["../../src/geocoding/jordan-research.service.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"jordan-research.service.js","sourceRoot":"","sources":["../../src/geocoding/jordan-research.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,6CAAmD;AACnD,qCAAqC;AACrC,wEAA6D;AAC7D,kDAA0B;AAC1B,uCAAyB;AACzB,2CAA6B;AAGtB,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;IAKb;IAJF,MAAM,GAAG,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAEjE,YAEmB,SAAkC;QAAlC,cAAS,GAAT,SAAS,CAAyB;IAClD,CAAC;IAEI,KAAK,CAAC,cAAc,CAAC,GAAW,EAAE,IAAa,EAAE,SAAyB,KAAK,EAAE,OAAO,GAAG,CAAC;QAClG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG;oBACX,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE;wBACL,YAAY,EAAE,mEAAmE;wBACjF,QAAQ,EAAE,mDAAmD;qBAChE;iBACJ,CAAC;gBACF,MAAM,QAAQ,GAAG,MAAM,KAAK,MAAM;oBAC9B,CAAC,CAAC,MAAM,eAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC;oBACrC,CAAC,CAAC,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/F,OAAO,QAAQ,CAAC,IAAI,CAAC;YACzB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,GAAG,UAAU,OAAO,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBAChB,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;YACpD,CAAC;QACL,CAAC;IACP,CAAC;IAKD,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,mLAAmL,CAAC;QAClM,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,yCAAyC,EAAE,QAAQ,kBAAkB,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/H,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC7B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC5C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBACjG,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAC7G,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAAC,CAAC;IACrE,CAAC;IAKD,KAAK,CAAC,kBAAkB;QACtB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,sFAAsF,CAAC,CAAC;YACtI,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,wDAAwD,EAAE,CAAC;YAGpH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,0FAA0F,CAAC,CAAC;YACvI,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YAChD,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAEpH,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;oFAC4C,YAAY;;;;;;OAMzF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,KAAK,EAAE,0BAA0B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAAC,CAAC;IAC1E,CAAC;IAKD,KAAK,CAAC,kBAAkB;QACtB,MAAM,MAAM,GAAG,6IAA6I,CAAC;QAC7J,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,mCAAmC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAC3F,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7G,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,KAAK,EAAE,0BAA0B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAAC,CAAC;IAC1E,CAAC;IAKD,KAAK,CAAC,gBAAgB;QAEpB,MAAM,KAAK,GAAG,CAAC,gCAAgC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,CAAC,gCAAgC,EAAE,mBAAmB,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,EAAE,CAAC;QAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACpB,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;oBACpC,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,EAAE,CAAC;oBAChC,KAAK,GAAG,IAAI,CAAC;oBACb,MAAM;gBACV,CAAC;YACL,CAAC;YACD,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,2EAA2E,CAAC;QAC5G,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC/D,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,gBAAgB,EAAE;SACxB,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,2BAA2B;YACjC,gBAAgB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC1C,OAAO,EAAE;gBACP,GAAG;gBACH,QAAQ;gBACR,QAAQ;gBACR,YAAY,EAAE,WAAW;gBACzB,GAAG,EAAE,wDAAwD;gBAC7D,IAAI,EAAE,kCAAkC;aACzC;YACD,kBAAkB,EAAE,oLAAoL;SACzM,CAAC;IACJ,CAAC;CACF,CAAA;AAjIY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,0BAAgB,EAAC,iCAAW,CAAC,CAAA;yDACF,oBAAU,oBAAV,oBAAU;GAL7B,qBAAqB,CAiIjC"}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { MapRefinementService } from './map-refinement.service';
|
||||||
|
import { CandidateStatus } from './entities/map-candidate.entity';
|
||||||
|
export declare class MapRefinementController {
|
||||||
|
private readonly refinementService;
|
||||||
|
constructor(refinementService: MapRefinementService);
|
||||||
|
suggest(req: any, dto: any): Promise<import("./entities/map-candidate.entity").MapCandidate>;
|
||||||
|
list(status?: CandidateStatus): Promise<any[]>;
|
||||||
|
approve(id: string): Promise<any>;
|
||||||
|
reject(id: string, body: {
|
||||||
|
reason: string;
|
||||||
|
}): Promise<import("./entities/map-candidate.entity").MapCandidate>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
"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.MapRefinementController = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const map_refinement_service_1 = require("./map-refinement.service");
|
||||||
|
const firebase_auth_guard_1 = require("../auth/guards/firebase-auth.guard");
|
||||||
|
const swagger_1 = require("@nestjs/swagger");
|
||||||
|
const map_candidate_entity_1 = require("./entities/map-candidate.entity");
|
||||||
|
let MapRefinementController = class MapRefinementController {
|
||||||
|
refinementService;
|
||||||
|
constructor(refinementService) {
|
||||||
|
this.refinementService = refinementService;
|
||||||
|
}
|
||||||
|
async suggest(req, dto) {
|
||||||
|
const userId = req.user?.uid || req.tenant?.id || 'anonymous';
|
||||||
|
return this.refinementService.suggestPlace(dto, userId);
|
||||||
|
}
|
||||||
|
async list(status) {
|
||||||
|
return this.refinementService.getCandidates(status);
|
||||||
|
}
|
||||||
|
async approve(id) {
|
||||||
|
return this.refinementService.approveCandidate(parseInt(id, 10));
|
||||||
|
}
|
||||||
|
async reject(id, body) {
|
||||||
|
return this.refinementService.rejectCandidate(parseInt(id, 10), body.reason);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.MapRefinementController = MapRefinementController;
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Post)('suggest'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Suggest a new location for the map (Client App)' }),
|
||||||
|
(0, swagger_1.ApiHeader)({ name: 'x-api-key', description: 'API Key for usage tracking' }),
|
||||||
|
__param(0, (0, common_1.Req)()),
|
||||||
|
__param(1, (0, common_1.Body)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [Object, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapRefinementController.prototype, "suggest", null);
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Get)('candidates'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'List suggested places for review (Dashboard)' }),
|
||||||
|
__param(0, (0, common_1.Query)('status')),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [String]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapRefinementController.prototype, "list", null);
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Patch)('candidates/:id/approve'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Approve a candidate and move to production (Dashboard)' }),
|
||||||
|
__param(0, (0, common_1.Param)('id')),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [String]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapRefinementController.prototype, "approve", null);
|
||||||
|
__decorate([
|
||||||
|
(0, swagger_1.ApiBearerAuth)(),
|
||||||
|
(0, common_1.UseGuards)(firebase_auth_guard_1.FirebaseAuthGuard),
|
||||||
|
(0, common_1.Patch)('candidates/:id/reject'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Reject a candidate (Dashboard)' }),
|
||||||
|
__param(0, (0, common_1.Param)('id')),
|
||||||
|
__param(1, (0, common_1.Body)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [String, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapRefinementController.prototype, "reject", null);
|
||||||
|
exports.MapRefinementController = MapRefinementController = __decorate([
|
||||||
|
(0, swagger_1.ApiTags)('map-refinement-places'),
|
||||||
|
(0, common_1.Controller)('map-refinement/places'),
|
||||||
|
__metadata("design:paramtypes", [map_refinement_service_1.MapRefinementService])
|
||||||
|
], MapRefinementController);
|
||||||
|
//# sourceMappingURL=map-refinement.controller.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"map-refinement.controller.js","sourceRoot":"","sources":["../../src/geocoding/map-refinement.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAkG;AAClG,qEAAgE;AAChE,4EAAuE;AACvE,6CAAkF;AAClF,0EAAkE;AAI3D,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IACL;IAA7B,YAA6B,iBAAuC;QAAvC,sBAAiB,GAAjB,iBAAiB,CAAsB;IAAG,CAAC;IAKlE,AAAN,KAAK,CAAC,OAAO,CAAQ,GAAQ,EAAU,GAAQ;QAE7C,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,WAAW,CAAC;QAC9D,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAMK,AAAN,KAAK,CAAC,IAAI,CAAkB,MAAwB;QAClD,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC;IAMK,AAAN,KAAK,CAAC,OAAO,CAAc,EAAU;QACnC,OAAO,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAMK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU,EAAU,IAAwB;QACpE,OAAO,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/E,CAAC;CACF,CAAA;AAnCY,0DAAuB;AAM5B;IAHL,IAAA,aAAI,EAAC,SAAS,CAAC;IACf,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAAC;IAC5E,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAC7D,WAAA,IAAA,YAAG,GAAE,CAAA;IAAY,WAAA,IAAA,aAAI,GAAE,CAAA;;;;sDAIrC;AAMK;IAJL,IAAA,uBAAa,GAAE;IACf,IAAA,kBAAS,EAAC,uCAAiB,CAAC;IAC5B,IAAA,YAAG,EAAC,YAAY,CAAC;IACjB,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC;IAC9D,WAAA,IAAA,cAAK,EAAC,QAAQ,CAAC,CAAA;;;;mDAE1B;AAMK;IAJL,IAAA,uBAAa,GAAE;IACf,IAAA,kBAAS,EAAC,uCAAiB,CAAC;IAC5B,IAAA,cAAK,EAAC,wBAAwB,CAAC;IAC/B,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,wDAAwD,EAAE,CAAC;IACrE,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;sDAEzB;AAMK;IAJL,IAAA,uBAAa,GAAE;IACf,IAAA,kBAAS,EAAC,uCAAiB,CAAC;IAC5B,IAAA,cAAK,EAAC,uBAAuB,CAAC;IAC9B,IAAA,sBAAY,EAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;IAC9C,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;IAAc,WAAA,IAAA,aAAI,GAAE,CAAA;;;;qDAE5C;kCAlCU,uBAAuB;IAFnC,IAAA,iBAAO,EAAC,uBAAuB,CAAC;IAChC,IAAA,mBAAU,EAAC,uBAAuB,CAAC;qCAEc,6CAAoB;GADzD,uBAAuB,CAmCnC"}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Repository, DataSource } from 'typeorm';
|
||||||
|
import { MapCandidate, CandidateStatus } from './entities/map-candidate.entity';
|
||||||
|
import { PlaceJordan } from './entities/place-jordan.entity';
|
||||||
|
import { PlaceSyria } from './entities/place-syria.entity';
|
||||||
|
import { PlaceEgypt } from './entities/place-egypt.entity';
|
||||||
|
export declare class MapRefinementService {
|
||||||
|
private dataSource;
|
||||||
|
private candidateRepository;
|
||||||
|
private jordanRepository;
|
||||||
|
private syriaRepository;
|
||||||
|
private egyptRepository;
|
||||||
|
private readonly logger;
|
||||||
|
constructor(dataSource: DataSource, candidateRepository: Repository<MapCandidate>, jordanRepository: Repository<PlaceJordan>, syriaRepository: Repository<PlaceSyria>, egyptRepository: Repository<PlaceEgypt>);
|
||||||
|
suggestPlace(dto: any, submittedBy: string): Promise<MapCandidate>;
|
||||||
|
runExternalVerification(candidateId: number): Promise<void>;
|
||||||
|
getCandidates(status?: CandidateStatus): Promise<any[]>;
|
||||||
|
approveCandidate(id: number): Promise<any>;
|
||||||
|
rejectCandidate(id: number, reason: string): Promise<MapCandidate>;
|
||||||
|
}
|
||||||
+208
@@ -0,0 +1,208 @@
|
|||||||
|
"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 MapRefinementService_1;
|
||||||
|
var _a, _b, _c, _d, _e;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.MapRefinementService = void 0;
|
||||||
|
const common_1 = require("@nestjs/common");
|
||||||
|
const typeorm_1 = require("@nestjs/typeorm");
|
||||||
|
const typeorm_2 = require("typeorm");
|
||||||
|
const map_candidate_entity_1 = require("./entities/map-candidate.entity");
|
||||||
|
const place_jordan_entity_1 = require("./entities/place-jordan.entity");
|
||||||
|
const place_syria_entity_1 = require("./entities/place-syria.entity");
|
||||||
|
const place_egypt_entity_1 = require("./entities/place-egypt.entity");
|
||||||
|
let MapRefinementService = MapRefinementService_1 = class MapRefinementService {
|
||||||
|
dataSource;
|
||||||
|
candidateRepository;
|
||||||
|
jordanRepository;
|
||||||
|
syriaRepository;
|
||||||
|
egyptRepository;
|
||||||
|
logger = new common_1.Logger(MapRefinementService_1.name);
|
||||||
|
constructor(dataSource, candidateRepository, jordanRepository, syriaRepository, egyptRepository) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.candidateRepository = candidateRepository;
|
||||||
|
this.jordanRepository = jordanRepository;
|
||||||
|
this.syriaRepository = syriaRepository;
|
||||||
|
this.egyptRepository = egyptRepository;
|
||||||
|
}
|
||||||
|
async suggestPlace(dto, submittedBy) {
|
||||||
|
const lat = parseFloat(dto.lat || dto.latitude);
|
||||||
|
const lng = parseFloat(dto.lng || dto.longitude);
|
||||||
|
const country = (dto.country || 'JORDAN').toUpperCase();
|
||||||
|
if (isNaN(lat) || isNaN(lng)) {
|
||||||
|
throw new Error('Invalid coordinates: Latitude and Longitude must be numbers');
|
||||||
|
}
|
||||||
|
this.logger.log(`📍 Suggesting place: ${dto.name} at [${lat}, ${lng}]. Performing spatial enrichment...`);
|
||||||
|
const enrichment = await this.dataSource.query(`
|
||||||
|
SELECT
|
||||||
|
g.id as gov_id, g.name_ar as gov_name,
|
||||||
|
d.id as dist_id, d.name_ar as dist_name,
|
||||||
|
s.id as sub_id, s.name_ar as sub_name,
|
||||||
|
n.id as neigh_id, n.name_ar as neigh_name
|
||||||
|
FROM (SELECT ST_SetSRID(ST_MakePoint($1, $2), 4326) as p) p
|
||||||
|
LEFT JOIN admin_boundaries g ON g.admin_level = 4 AND ST_Within(p.p::geometry, g.geom::geometry)
|
||||||
|
LEFT JOIN admin_boundaries d ON d.admin_level = 6 AND ST_Within(p.p::geometry, d.geom::geometry)
|
||||||
|
LEFT JOIN admin_boundaries s ON s.admin_level = 8 AND ST_Within(p.p::geometry, s.geom::geometry)
|
||||||
|
LEFT JOIN neighborhood_polygons n ON ST_Within(p.p::geometry, n.geometry::geometry)
|
||||||
|
LIMIT 1
|
||||||
|
`, [lng, lat]);
|
||||||
|
const spatialData = enrichment[0] || {};
|
||||||
|
const isArabic = (text) => /[\u0600-\u06FF]/.test(text);
|
||||||
|
const nameAr = dto.name_ar || (isArabic(dto.name) ? dto.name : null);
|
||||||
|
const nameEn = dto.name_en || (!isArabic(dto.name) ? dto.name : null);
|
||||||
|
const candidate = this.candidateRepository.create({
|
||||||
|
name: dto.name,
|
||||||
|
name_ar: nameAr,
|
||||||
|
name_en: nameEn,
|
||||||
|
category: dto.category,
|
||||||
|
address: dto.address,
|
||||||
|
latitude: lat,
|
||||||
|
longitude: lng,
|
||||||
|
submittedBy,
|
||||||
|
status: map_candidate_entity_1.CandidateStatus.PENDING,
|
||||||
|
country: country,
|
||||||
|
location: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: [lng, lat],
|
||||||
|
},
|
||||||
|
governorate_id: spatialData.gov_id,
|
||||||
|
district_id: spatialData.dist_id,
|
||||||
|
sub_district_id: spatialData.sub_id,
|
||||||
|
neighborhood_id: spatialData.neigh_id
|
||||||
|
});
|
||||||
|
const saved = await this.candidateRepository.save(candidate);
|
||||||
|
this.logger.log(`✅ Success: Candidate ${saved.id} enriched with Gov:${saved.governorate_id}, Neigh:${spatialData.neigh_id}`);
|
||||||
|
this.runExternalVerification(saved.id).catch(err => this.logger.error(`❌ Verification failed for ${saved.id}: ${err.message}`));
|
||||||
|
return {
|
||||||
|
...saved,
|
||||||
|
governorate_name: spatialData.gov_name,
|
||||||
|
district_name: spatialData.dist_name,
|
||||||
|
neighborhood_name: spatialData.neigh_name,
|
||||||
|
location_wkt: `POINT(${lng} ${lat})`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async runExternalVerification(candidateId) {
|
||||||
|
const candidate = await this.candidateRepository.findOne({ where: { id: candidateId } });
|
||||||
|
if (!candidate)
|
||||||
|
return;
|
||||||
|
this.logger.log(`🔍 Starting automated verification for candidate ${candidate.id}...`);
|
||||||
|
try {
|
||||||
|
const axios = require('axios');
|
||||||
|
const searchUrl = `https://duckduckgo.com/html/?q=${candidate.latitude},${candidate.longitude}`;
|
||||||
|
const response = await axios.get(searchUrl, {
|
||||||
|
headers: {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
||||||
|
},
|
||||||
|
timeout: 10000
|
||||||
|
});
|
||||||
|
const html = response.data;
|
||||||
|
const titleMatch = html.match(/<title>([^<]+)<\/title>/);
|
||||||
|
if (titleMatch) {
|
||||||
|
let officialName = titleMatch[1].replace(' at DuckDuckGo', '').replace(' - DuckDuckGo', '').trim();
|
||||||
|
const isCoordinates = /^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/.test(officialName);
|
||||||
|
if (!isCoordinates && officialName.length > 5) {
|
||||||
|
candidate.verified_name = officialName;
|
||||||
|
const cleanUser = candidate.name.toLowerCase().trim();
|
||||||
|
const cleanOfficial = officialName.toLowerCase();
|
||||||
|
if (cleanOfficial.includes(cleanUser) || cleanUser.includes(cleanOfficial)) {
|
||||||
|
candidate.confidence_score = 90;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidate.confidence_score = 60;
|
||||||
|
}
|
||||||
|
this.logger.log(`🎯 Verified: Found "${officialName}" near suggestion. Trust: ${candidate.confidence_score}%`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
candidate.confidence_score = 10;
|
||||||
|
this.logger.log(`⚠️ No specific POI name found for coordinates ${candidate.latitude},${candidate.longitude}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidate.verification_metadata = {
|
||||||
|
last_check: new Date().toISOString(),
|
||||||
|
source: 'DDG_SCRAPE'
|
||||||
|
};
|
||||||
|
await this.candidateRepository.save(candidate);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this.logger.error(`Automated verification error: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async getCandidates(status) {
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
c.*,
|
||||||
|
g.name_ar as governorate_name,
|
||||||
|
d.name_ar as district_name,
|
||||||
|
n.name_ar as neighborhood_name
|
||||||
|
FROM map_candidates c
|
||||||
|
LEFT JOIN admin_boundaries g ON c.governorate_id = g.id
|
||||||
|
LEFT JOIN admin_boundaries d ON c.district_id = d.id
|
||||||
|
LEFT JOIN neighborhood_polygons n ON c.neighborhood_id = n.id
|
||||||
|
${status ? 'WHERE c.status = $1' : ''}
|
||||||
|
ORDER BY c.created_at DESC
|
||||||
|
`;
|
||||||
|
return this.candidateRepository.query(query, status ? [status] : []);
|
||||||
|
}
|
||||||
|
async approveCandidate(id) {
|
||||||
|
const candidate = await this.candidateRepository.findOne({ where: { id } });
|
||||||
|
if (!candidate)
|
||||||
|
throw new common_1.NotFoundException('Candidate not found');
|
||||||
|
const placeData = {
|
||||||
|
latitude: candidate.latitude,
|
||||||
|
longitude: candidate.longitude,
|
||||||
|
name: candidate.name,
|
||||||
|
name_ar: candidate.name_ar,
|
||||||
|
name_en: candidate.name_en,
|
||||||
|
category: candidate.category,
|
||||||
|
address: candidate.address,
|
||||||
|
description: candidate.description,
|
||||||
|
location: candidate.location,
|
||||||
|
source: `suggested_by_${candidate.submittedBy}`,
|
||||||
|
};
|
||||||
|
let repo;
|
||||||
|
switch (candidate.country) {
|
||||||
|
case map_candidate_entity_1.CountryCode.SYRIA:
|
||||||
|
repo = this.syriaRepository;
|
||||||
|
break;
|
||||||
|
case map_candidate_entity_1.CountryCode.EGYPT:
|
||||||
|
repo = this.egyptRepository;
|
||||||
|
break;
|
||||||
|
default: repo = this.jordanRepository;
|
||||||
|
}
|
||||||
|
const approvedPlace = repo.create(placeData);
|
||||||
|
await repo.save(approvedPlace);
|
||||||
|
candidate.status = map_candidate_entity_1.CandidateStatus.APPROVED;
|
||||||
|
await this.candidateRepository.save(candidate);
|
||||||
|
this.logger.log(`✅ Approved candidate ${id}: ${candidate.name} moved to production.`);
|
||||||
|
return { success: true, place: approvedPlace };
|
||||||
|
}
|
||||||
|
async rejectCandidate(id, reason) {
|
||||||
|
const candidate = await this.candidateRepository.findOne({ where: { id } });
|
||||||
|
if (!candidate)
|
||||||
|
throw new common_1.NotFoundException('Candidate not found');
|
||||||
|
candidate.status = map_candidate_entity_1.CandidateStatus.REJECTED;
|
||||||
|
candidate.rejectionReason = reason;
|
||||||
|
return this.candidateRepository.save(candidate);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.MapRefinementService = MapRefinementService;
|
||||||
|
exports.MapRefinementService = MapRefinementService = MapRefinementService_1 = __decorate([
|
||||||
|
(0, common_1.Injectable)(),
|
||||||
|
__param(1, (0, typeorm_1.InjectRepository)(map_candidate_entity_1.MapCandidate)),
|
||||||
|
__param(2, (0, typeorm_1.InjectRepository)(place_jordan_entity_1.PlaceJordan)),
|
||||||
|
__param(3, (0, typeorm_1.InjectRepository)(place_syria_entity_1.PlaceSyria)),
|
||||||
|
__param(4, (0, typeorm_1.InjectRepository)(place_egypt_entity_1.PlaceEgypt)),
|
||||||
|
__metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.DataSource !== "undefined" && typeorm_2.DataSource) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, typeof (_c = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _c : Object, typeof (_d = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _d : Object, typeof (_e = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _e : Object])
|
||||||
|
], MapRefinementService);
|
||||||
|
//# sourceMappingURL=map-refinement.service.js.map
|
||||||
File diff suppressed because one or more lines are too long
Vendored
+14
-2
@@ -9,9 +9,21 @@ const swagger_1 = require("@nestjs/swagger");
|
|||||||
const helmet_1 = __importDefault(require("helmet"));
|
const helmet_1 = __importDefault(require("helmet"));
|
||||||
const app_module_1 = require("./app.module");
|
const app_module_1 = require("./app.module");
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await core_1.NestFactory.create(app_module_1.AppModule);
|
const app = await core_1.NestFactory.create(app_module_1.AppModule, {
|
||||||
|
logger: ['error', 'warn', 'log', 'debug', 'verbose'],
|
||||||
|
});
|
||||||
|
const httpAdapter = app.getHttpAdapter();
|
||||||
|
if (httpAdapter && httpAdapter.getInstance && typeof httpAdapter.getInstance().set === 'function') {
|
||||||
|
httpAdapter.getInstance().set('trust proxy', 1);
|
||||||
|
}
|
||||||
app.use((0, helmet_1.default)());
|
app.use((0, helmet_1.default)());
|
||||||
app.enableCors();
|
app.enableCors({
|
||||||
|
origin: process.env.ALLOWED_ORIGINS
|
||||||
|
? process.env.ALLOWED_ORIGINS.split(',')
|
||||||
|
: ['http://localhost:3204', 'http://localhost:5173', 'https://map-saas.intaleqapp.com'],
|
||||||
|
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
|
||||||
|
credentials: true,
|
||||||
|
});
|
||||||
app.setGlobalPrefix('api');
|
app.setGlobalPrefix('api');
|
||||||
app.useGlobalPipes(new common_1.ValidationPipe({
|
app.useGlobalPipes(new common_1.ValidationPipe({
|
||||||
whitelist: true,
|
whitelist: true,
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;AAAA,uCAAsD;AACtD,2CAAgD;AAChD,6CAAiE;AACjE,oDAA4B;AAC5B,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAGhD,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,GAAE,CAAC,CAAC;IAGlB,GAAG,CAAC,UAAU,EAAE,CAAC;IAGjB,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAG3B,GAAG,CAAC,cAAc,CAAC,IAAI,uBAAc,CAAC;QACpC,SAAS,EAAE,IAAI;QACf,oBAAoB,EAAE,IAAI;QAC1B,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC,CAAC;IAGJ,MAAM,MAAM,GAAG,IAAI,yBAAe,EAAE;SACjC,QAAQ,CAAC,yBAAyB,CAAC;SACnC,cAAc,CAAC,wEAAwE,CAAC;SACxF,UAAU,CAAC,KAAK,CAAC;SACjB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,WAAW,CAAC;SAC3E,MAAM,CAAC,MAAM,CAAC;SACd,MAAM,CAAC,WAAW,CAAC;SACnB,MAAM,CAAC,WAAW,CAAC;SACnB,KAAK,EAAE,CAAC;IAEX,MAAM,QAAQ,GAAG,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3D,uBAAa,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC1C,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,qDAAqD,IAAI,MAAM,CAAC,CAAC;AAC/E,CAAC;AACD,SAAS,EAAE,CAAC"}
|
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;AAAA,uCAA2C;AAC3C,2CAAgD;AAChD,6CAAiE;AACjE,oDAA4B;AAE5B,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,EAAE;QAC9C,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC;KACrD,CAAC,CAAC;IAGH,MAAM,WAAW,GAAG,GAAG,CAAC,cAAc,EAAE,CAAC;IACzC,IAAI,WAAW,IAAI,WAAW,CAAC,WAAW,IAAI,OAAO,WAAW,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAClG,WAAW,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAGD,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,GAAE,CAAC,CAAC;IAGlB,GAAG,CAAC,UAAU,CAAC;QACb,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;YACjC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;YACxC,CAAC,CAAC,CAAC,uBAAuB,EAAE,uBAAuB,EAAE,iCAAiC,CAAC;QACzF,OAAO,EAAE,wCAAwC;QACjD,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAGH,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAG3B,GAAG,CAAC,cAAc,CAAC,IAAI,uBAAc,CAAC;QACpC,SAAS,EAAE,IAAI;QACf,oBAAoB,EAAE,IAAI;QAC1B,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC,CAAC;IAGJ,MAAM,MAAM,GAAG,IAAI,yBAAe,EAAE;SACjC,QAAQ,CAAC,yBAAyB,CAAC;SACnC,cAAc,CAAC,wEAAwE,CAAC;SACxF,UAAU,CAAC,KAAK,CAAC;SACjB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,WAAW,CAAC;SAC3E,MAAM,CAAC,MAAM,CAAC;SACd,MAAM,CAAC,WAAW,CAAC;SACnB,MAAM,CAAC,WAAW,CAAC;SACnB,KAAK,EAAE,CAAC;IAEX,MAAM,QAAQ,GAAG,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3D,uBAAa,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC1C,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,qDAAqD,IAAI,MAAM,CAAC,CAAC;AAC/E,CAAC;AACD,SAAS,EAAE,CAAC"}
|
||||||
@@ -7,6 +7,10 @@ export declare class CandidateRoad {
|
|||||||
lengthMeters: number;
|
lengthMeters: number;
|
||||||
confidence: number;
|
confidence: number;
|
||||||
status: string;
|
status: string;
|
||||||
|
source: string;
|
||||||
|
name: string;
|
||||||
|
highway: string;
|
||||||
|
oneway: number;
|
||||||
discoveredAt: Date;
|
discoveredAt: Date;
|
||||||
reviewedAt: Date;
|
reviewedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -20,6 +20,10 @@ let CandidateRoad = class CandidateRoad {
|
|||||||
lengthMeters;
|
lengthMeters;
|
||||||
confidence;
|
confidence;
|
||||||
status;
|
status;
|
||||||
|
source;
|
||||||
|
name;
|
||||||
|
highway;
|
||||||
|
oneway;
|
||||||
discoveredAt;
|
discoveredAt;
|
||||||
reviewedAt;
|
reviewedAt;
|
||||||
};
|
};
|
||||||
@@ -62,6 +66,22 @@ __decorate([
|
|||||||
(0, typeorm_1.Column)({ default: 'pending' }),
|
(0, typeorm_1.Column)({ default: 'pending' }),
|
||||||
__metadata("design:type", String)
|
__metadata("design:type", String)
|
||||||
], CandidateRoad.prototype, "status", void 0);
|
], CandidateRoad.prototype, "status", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ default: 'telemetry' }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], CandidateRoad.prototype, "source", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], CandidateRoad.prototype, "name", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'varchar', length: 32, nullable: true }),
|
||||||
|
__metadata("design:type", String)
|
||||||
|
], CandidateRoad.prototype, "highway", void 0);
|
||||||
|
__decorate([
|
||||||
|
(0, typeorm_1.Column)({ type: 'smallint', default: 0 }),
|
||||||
|
__metadata("design:type", Number)
|
||||||
|
], CandidateRoad.prototype, "oneway", void 0);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, typeorm_1.CreateDateColumn)(),
|
(0, typeorm_1.CreateDateColumn)(),
|
||||||
__metadata("design:type", Date)
|
__metadata("design:type", Date)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"candidate-road.entity.js","sourceRoot":"","sources":["../../src/maps/candidate-road.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0F;AASnF,IAAM,aAAa,GAAnB,MAAM,aAAa;IAExB,EAAE,CAAS;IAWX,QAAQ,CAAM;IAKd,iBAAiB,CAAS;IAK1B,WAAW,CAAS;IAKpB,YAAY,CAAS;IAKrB,YAAY,CAAS;IAKrB,UAAU,CAAS;IAKnB,MAAM,CAAS;IAGf,YAAY,CAAO;IAGnB,UAAU,CAAO;CAClB,CAAA;AAlDY,sCAAa;AAExB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;yCACpB;AAWX;IAPC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,WAAW;QACjB,kBAAkB,EAAE,YAAY;QAChC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,KAAK;KAChB,CAAC;IACD,IAAA,eAAK,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;+CACX;AAKd;IADC,IAAA,gBAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;wDACJ;AAK1B;IADC,IAAA,gBAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;kDACV;AAKpB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;mDACX;AAKrB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;mDACX;AAKrB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;iDACb;AAKnB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;;6CAChB;AAGf;IADC,IAAA,0BAAgB,GAAE;8BACL,IAAI;mDAAC;AAGnB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BAClC,IAAI;iDAAC;wBAjDN,aAAa;IADzB,IAAA,gBAAM,EAAC,iBAAiB,CAAC;GACb,aAAa,CAkDzB"}
|
{"version":3,"file":"candidate-road.entity.js","sourceRoot":"","sources":["../../src/maps/candidate-road.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0F;AASnF,IAAM,aAAa,GAAnB,MAAM,aAAa;IAExB,EAAE,CAAS;IAWX,QAAQ,CAAM;IAKd,iBAAiB,CAAS;IAK1B,WAAW,CAAS;IAKpB,YAAY,CAAS;IAKrB,YAAY,CAAS;IAKrB,UAAU,CAAS;IAKnB,MAAM,CAAS;IAKf,MAAM,CAAS;IAKf,IAAI,CAAS;IAKb,OAAO,CAAS;IAMhB,MAAM,CAAS;IAGf,YAAY,CAAO;IAGnB,UAAU,CAAO;CAClB,CAAA;AAvEY,sCAAa;AAExB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;yCACpB;AAWX;IAPC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,WAAW;QACjB,kBAAkB,EAAE,YAAY;QAChC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,KAAK;KAChB,CAAC;IACD,IAAA,eAAK,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;;+CACX;AAKd;IADC,IAAA,gBAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;wDACJ;AAK1B;IADC,IAAA,gBAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;kDACV;AAKpB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;mDACX;AAKrB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;mDACX;AAKrB;IADC,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;iDACb;AAKnB;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;;6CAChB;AAKf;IADC,IAAA,gBAAM,EAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;;6CAClB;AAKf;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2CAC5C;AAKb;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CACxC;AAMhB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;6CAC1B;AAGf;IADC,IAAA,0BAAgB,GAAE;8BACL,IAAI;mDAAC;AAGnB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;8BAClC,IAAI;iDAAC;wBAtEN,aAAa;IADzB,IAAA,gBAAM,EAAC,iBAAiB,CAAC;GACb,aAAa,CAuEzB"}
|
||||||
+10
-2
@@ -1,16 +1,24 @@
|
|||||||
|
import type { Response } from 'express';
|
||||||
import { MapsService } from './maps.service';
|
import { MapsService } from './maps.service';
|
||||||
export declare class MapsController {
|
export declare class MapsController {
|
||||||
private readonly mapsService;
|
private readonly mapsService;
|
||||||
constructor(mapsService: MapsService);
|
constructor(mapsService: MapsService);
|
||||||
|
syncRoutes(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
}>;
|
||||||
|
getStyleJson(theme: string, res: Response): Promise<any>;
|
||||||
getRoute(query: any): Promise<{
|
getRoute(query: any): Promise<{
|
||||||
|
routeName: any;
|
||||||
|
tags: any;
|
||||||
distance: any;
|
distance: any;
|
||||||
duration: number;
|
duration: any;
|
||||||
trafficAwareDuration: number;
|
|
||||||
trafficFactor: number;
|
trafficFactor: number;
|
||||||
startName: string;
|
startName: string;
|
||||||
endName: string;
|
endName: string;
|
||||||
points: any;
|
points: any;
|
||||||
bbox: any;
|
bbox: any;
|
||||||
|
instructions: any;
|
||||||
alternatives: any;
|
alternatives: any;
|
||||||
}>;
|
}>;
|
||||||
getConfig(): Promise<{
|
getConfig(): Promise<{
|
||||||
|
|||||||
+104
-1
@@ -1,10 +1,43 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
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;
|
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);
|
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;
|
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;
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||||
};
|
};
|
||||||
|
var __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||||
};
|
};
|
||||||
@@ -15,6 +48,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
exports.MapsController = void 0;
|
exports.MapsController = void 0;
|
||||||
const common_1 = require("@nestjs/common");
|
const common_1 = require("@nestjs/common");
|
||||||
const swagger_1 = require("@nestjs/swagger");
|
const swagger_1 = require("@nestjs/swagger");
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
const maps_service_1 = require("./maps.service");
|
const maps_service_1 = require("./maps.service");
|
||||||
const api_key_guard_1 = require("../common/guards/api-key.guard");
|
const api_key_guard_1 = require("../common/guards/api-key.guard");
|
||||||
let MapsController = class MapsController {
|
let MapsController = class MapsController {
|
||||||
@@ -22,6 +57,55 @@ let MapsController = class MapsController {
|
|||||||
constructor(mapsService) {
|
constructor(mapsService) {
|
||||||
this.mapsService = mapsService;
|
this.mapsService = mapsService;
|
||||||
}
|
}
|
||||||
|
async syncRoutes() {
|
||||||
|
return this.mapsService.requestRoutingSync();
|
||||||
|
}
|
||||||
|
async getStyleJson(theme, res) {
|
||||||
|
const isDark = theme === 'obsidian';
|
||||||
|
const filename = isDark ? 'style-dark.json' : 'style.json';
|
||||||
|
const fallbackFilename = 'style.json';
|
||||||
|
const pathsToCheck = [
|
||||||
|
path.join('/data', filename),
|
||||||
|
path.join(process.cwd(), '../../', filename),
|
||||||
|
path.join(process.cwd(), filename),
|
||||||
|
path.join('/data', fallbackFilename),
|
||||||
|
path.join(process.cwd(), '../../', fallbackFilename),
|
||||||
|
path.join(process.cwd(), fallbackFilename),
|
||||||
|
];
|
||||||
|
let stylePath = '';
|
||||||
|
for (const p of pathsToCheck) {
|
||||||
|
if (fs.existsSync(p)) {
|
||||||
|
stylePath = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!stylePath) {
|
||||||
|
return res.status(404).send('Style not found');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const styleRaw = fs.readFileSync(stylePath, 'utf8');
|
||||||
|
const styleObj = JSON.parse(styleRaw);
|
||||||
|
if (theme === 'light') {
|
||||||
|
styleObj.layers.forEach((layer) => {
|
||||||
|
if (layer.id === 'background') {
|
||||||
|
layer.paint['background-color'] = '#FFFFFF';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (theme === 'obsidian') {
|
||||||
|
styleObj.layers.forEach((layer) => {
|
||||||
|
if (layer.id === 'background') {
|
||||||
|
layer.paint['background-color'] = '#101014';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.send(styleObj);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
res.status(500).send('Error parsing style.json');
|
||||||
|
}
|
||||||
|
}
|
||||||
async getRoute(query) {
|
async getRoute(query) {
|
||||||
const waypoints = [];
|
const waypoints = [];
|
||||||
if (query.fromLat && query.fromLng) {
|
if (query.fromLat && query.fromLng) {
|
||||||
@@ -45,13 +129,32 @@ let MapsController = class MapsController {
|
|||||||
waypoints.push([parseFloat(query.toLat), parseFloat(query.toLng)]);
|
waypoints.push([parseFloat(query.toLat), parseFloat(query.toLng)]);
|
||||||
}
|
}
|
||||||
const profile = query.profile || 'car';
|
const profile = query.profile || 'car';
|
||||||
return this.mapsService.getRoute(waypoints, profile);
|
const steps = query.steps === 'true';
|
||||||
|
const locale = query.locale || 'en';
|
||||||
|
const alternatives = query.alternatives === 'true';
|
||||||
|
return this.mapsService.getRoute(waypoints, profile, steps, locale, alternatives);
|
||||||
}
|
}
|
||||||
async getConfig() {
|
async getConfig() {
|
||||||
return this.mapsService.getMapConfig();
|
return this.mapsService.getMapConfig();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
exports.MapsController = MapsController;
|
exports.MapsController = MapsController;
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Post)('sync-routes'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Request GraphHopper routing sync 🔄' }),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", []),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapsController.prototype, "syncRoutes", null);
|
||||||
|
__decorate([
|
||||||
|
(0, common_1.Get)('style.json'),
|
||||||
|
(0, swagger_1.ApiOperation)({ summary: 'Get MapLibre style JSON 🎨' }),
|
||||||
|
__param(0, (0, common_1.Query)('theme')),
|
||||||
|
__param(1, (0, common_1.Res)()),
|
||||||
|
__metadata("design:type", Function),
|
||||||
|
__metadata("design:paramtypes", [String, Object]),
|
||||||
|
__metadata("design:returntype", Promise)
|
||||||
|
], MapsController.prototype, "getStyleJson", null);
|
||||||
__decorate([
|
__decorate([
|
||||||
(0, common_1.Get)('route'),
|
(0, common_1.Get)('route'),
|
||||||
(0, swagger_1.ApiOperation)({ summary: 'Calculate a route with dynamic waypoints 🚗' }),
|
(0, swagger_1.ApiOperation)({ summary: 'Calculate a route with dynamic waypoints 🚗' }),
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"maps.controller.js","sourceRoot":"","sources":["../../src/maps/maps.controller.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"maps.controller.js","sourceRoot":"","sources":["../../src/maps/maps.controller.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+15
-5
@@ -1,26 +1,36 @@
|
|||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository, DataSource } from 'typeorm';
|
||||||
import { RoadSegmentStat } from './road-stat.entity';
|
import { RoadSegmentStat } from './road-stat.entity';
|
||||||
import { TrafficGridService } from './traffic-grid.service';
|
import { TrafficGridService } from './traffic-grid.service';
|
||||||
import { GeocodingService } from '../geocoding/geocoding.service';
|
import { GeocodingService } from '../geocoding/geocoding.service';
|
||||||
|
import { RedisService } from '../common/redis.service';
|
||||||
export declare class MapsService {
|
export declare class MapsService {
|
||||||
private configService;
|
private configService;
|
||||||
private roadStatRepo;
|
private roadStatRepo;
|
||||||
private trafficGrid;
|
private trafficGrid;
|
||||||
private geocodingService;
|
private geocodingService;
|
||||||
|
private dataSource;
|
||||||
|
private redisService;
|
||||||
private readonly graphHopperUrl;
|
private readonly graphHopperUrl;
|
||||||
constructor(configService: ConfigService, roadStatRepo: Repository<RoadSegmentStat>, trafficGrid: TrafficGridService, geocodingService: GeocodingService);
|
constructor(configService: ConfigService, roadStatRepo: Repository<RoadSegmentStat>, trafficGrid: TrafficGridService, geocodingService: GeocodingService, dataSource: DataSource, redisService: RedisService);
|
||||||
getRoute(waypoints: [number, number][], profile?: string): Promise<{
|
requestRoutingSync(): Promise<{
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
}>;
|
||||||
|
getRoute(waypoints: [number, number][], profile?: string, steps?: boolean, locale?: string, alternatives?: boolean): Promise<{
|
||||||
|
routeName: any;
|
||||||
|
tags: any;
|
||||||
distance: any;
|
distance: any;
|
||||||
duration: number;
|
duration: any;
|
||||||
trafficAwareDuration: number;
|
|
||||||
trafficFactor: number;
|
trafficFactor: number;
|
||||||
startName: string;
|
startName: string;
|
||||||
endName: string;
|
endName: string;
|
||||||
points: any;
|
points: any;
|
||||||
bbox: any;
|
bbox: any;
|
||||||
|
instructions: any;
|
||||||
alternatives: any;
|
alternatives: any;
|
||||||
}>;
|
}>;
|
||||||
|
private getRouteName;
|
||||||
private decodePolyline;
|
private decodePolyline;
|
||||||
getMapConfig(): Promise<{
|
getMapConfig(): Promise<{
|
||||||
center: number[];
|
center: number[];
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user