feat(gps): фокус геозоны на карте, город по умолчанию для всех карт, доступ к GPS по пользователям/ролям (админ)

This commit is contained in:
2026-08-26 10:20:38 +03:00
parent 3e8849019a
commit 8f5789ec28
15 changed files with 718 additions and 122 deletions

View File

@@ -9,6 +9,8 @@ import {
gpsGroupAssets,
gpsAssetSubscribers,
gpsSettings,
roles,
roleMembers,
type GpsAsset,
type GpsPosition,
type GpsGeozone,
@@ -462,7 +464,16 @@ export class GpsStorage {
// =====================
/** Настройки GPS организации; если строки нет — дефолты */
async getSettings(organizationId: number): Promise<{ jitterMeters: number; maxJumpSpeedKmh: number; tripStopMinutes: number }> {
async getSettings(organizationId: number): Promise<{
jitterMeters: number;
maxJumpSpeedKmh: number;
tripStopMinutes: number;
defaultLat: number | null;
defaultLng: number | null;
defaultZoom: number | null;
allowedUserIds: number[] | null;
allowedRoleIds: number[] | null;
}> {
const [row] = await db
.select()
.from(gpsSettings)
@@ -471,12 +482,26 @@ export class GpsStorage {
jitterMeters: row?.jitterMeters ?? 25,
maxJumpSpeedKmh: row?.maxJumpSpeedKmh ?? 250,
tripStopMinutes: row?.tripStopMinutes ?? 10,
defaultLat: row?.defaultLat ?? null,
defaultLng: row?.defaultLng ?? null,
defaultZoom: row?.defaultZoom ?? null,
allowedUserIds: row?.allowedUserIds ?? null,
allowedRoleIds: row?.allowedRoleIds ?? null,
};
}
async upsertSettings(
organizationId: number,
settings: { jitterMeters: number; maxJumpSpeedKmh: number; tripStopMinutes: number }
settings: {
jitterMeters: number;
maxJumpSpeedKmh: number;
tripStopMinutes: number;
defaultLat: number | null;
defaultLng: number | null;
defaultZoom: number | null;
allowedUserIds: number[] | null;
allowedRoleIds: number[] | null;
}
): Promise<GpsSettings> {
const [row] = await db
.insert(gpsSettings)
@@ -488,6 +513,16 @@ export class GpsStorage {
.returning();
return row;
}
/** Организационные роли пользователя (через role_members) в рамках организации */
async getUserRoleIds(userId: number, organizationId: number): Promise<number[]> {
const rows = await db
.select({ roleId: roleMembers.roleId })
.from(roleMembers)
.innerJoin(roles, eq(roleMembers.roleId, roles.id))
.where(and(eq(roleMembers.userId, userId), eq(roles.organizationId, organizationId)));
return rows.map((r) => r.roleId);
}
}
export const gpsStorage = new GpsStorage();