Skip to content

Commit fa29b83

Browse files
committed
refactor: update user and internal squad handling to use bigint IDs
1 parent 326784b commit fa29b83

File tree

11 files changed

+122
-90
lines changed

11 files changed

+122
-90
lines changed

docker-compose-db-local.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ services:
44
container_name: remnawave-db-local
55
hostname: remnawave-db-local
66
restart: always
7+
shm_size: 4gb
78
env_file:
89
- .env
910
environment:
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-- 1. Add new column
2+
ALTER TABLE "internal_squad_members" ADD COLUMN "user_id" BIGINT;
3+
4+
-- 2. Copy data from uuid to t_id
5+
UPDATE "internal_squad_members" ism
6+
SET "user_id" = u."t_id"
7+
FROM "users" u
8+
WHERE ism."user_uuid" = u."uuid";
9+
10+
-- 3. NOT NULL
11+
ALTER TABLE "internal_squad_members" ALTER COLUMN "user_id" SET NOT NULL;
12+
13+
-- 4. Delete the old column
14+
ALTER TABLE "internal_squad_members" DROP CONSTRAINT "internal_squad_members_user_uuid_fkey";
15+
16+
DROP INDEX "internal_squad_members_user_uuid_idx";
17+
18+
ALTER TABLE "internal_squad_members" DROP CONSTRAINT "internal_squad_members_pkey";
19+
20+
ALTER TABLE "internal_squad_members" DROP COLUMN "user_uuid";
21+
22+
-- 5. Create new keys and indexes
23+
ALTER TABLE "internal_squad_members" ADD CONSTRAINT "internal_squad_members_pkey" PRIMARY KEY ("internal_squad_uuid", "user_id");
24+
25+
CREATE INDEX "internal_squad_members_user_id_idx" ON "internal_squad_members"("user_id");
26+
27+
ALTER TABLE "internal_squad_members" ADD CONSTRAINT "internal_squad_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("t_id") ON DELETE CASCADE ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,14 @@ model InternalSquads {
387387

388388
model InternalSquadMembers {
389389
internalSquadUuid String @map("internal_squad_uuid") @db.Uuid
390-
userUuid String @map("user_uuid") @db.Uuid
390+
userId BigInt @map("user_id")
391391
392392
internalSquad InternalSquads @relation(fields: [internalSquadUuid], references: [uuid], onDelete: Cascade)
393-
user Users @relation(fields: [userUuid], references: [uuid], onDelete: Cascade)
393+
user Users @relation(fields: [userId], references: [tId], onDelete: Cascade)
394394
395-
@@id([internalSquadUuid, userUuid])
395+
@@id([internalSquadUuid, userId])
396396
@@index([internalSquadUuid])
397-
@@index([userUuid])
397+
@@index([userId])
398398
@@map("internal_squad_members")
399399
}
400400

src/modules/hosts/queries/get-hosts-for-user/get-hosts-for-user.handler.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
22
import { Logger } from '@nestjs/common';
33

4-
import { ICommandResponse } from '@common/types/command-response.type';
54
import { ERRORS } from '@libs/contracts/constants';
65

7-
import { HostsEntity } from '@modules/hosts';
8-
96
import { HostsRepository } from '../../repositories/hosts.repository';
107
import { GetHostsForUserQuery } from './get-hosts-for-user.query';
118

129
@QueryHandler(GetHostsForUserQuery)
13-
export class GetHostsForUserHandler implements IQueryHandler<
14-
GetHostsForUserQuery,
15-
ICommandResponse<HostsEntity[]>
16-
> {
10+
export class GetHostsForUserHandler implements IQueryHandler<GetHostsForUserQuery> {
1711
private readonly logger = new Logger(GetHostsForUserHandler.name);
1812
constructor(private readonly hostsRepository: HostsRepository) {}
1913

20-
async execute(query: GetHostsForUserQuery): Promise<ICommandResponse<HostsEntity[]>> {
14+
async execute(query: GetHostsForUserQuery) {
2115
try {
22-
const hosts = await this.hostsRepository.findActiveHostsByUserUuid(
23-
query.userUuid,
16+
const hosts = await this.hostsRepository.findActiveHostsByUserId(
17+
query.userId,
2418
query.returnDisabledHosts,
2519
query.returnHiddenHosts,
2620
);
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
export class GetHostsForUserQuery {
1+
import { Query } from '@nestjs/cqrs';
2+
3+
import { ICommandResponse } from '@common/types/command-response.type';
4+
5+
import { HostWithRawInbound } from '@modules/hosts/entities/host-with-inbound-tag.entity';
6+
7+
export class GetHostsForUserQuery extends Query<ICommandResponse<HostWithRawInbound[]>> {
28
constructor(
3-
public readonly userUuid: string,
9+
public readonly userId: bigint,
410
public readonly returnDisabledHosts: boolean,
511
public readonly returnHiddenHosts: boolean,
6-
) {}
12+
) {
13+
super();
14+
}
715
}

src/modules/hosts/repositories/hosts.repository.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { Injectable } from '@nestjs/common';
88

99
import { TxKyselyService } from '@common/database';
1010
import { ICrud } from '@common/types/crud-port';
11-
import { getKyselyUuid } from '@common/helpers';
1211
import { TSecurityLayers } from '@libs/contracts/constants';
1312

1413
import { HostWithRawInbound } from '../entities/host-with-inbound-tag.entity';
@@ -154,8 +153,8 @@ export class HostsRepository implements ICrud<HostsEntity> {
154153
return !!result;
155154
}
156155

157-
public async findActiveHostsByUserUuid(
158-
userUuid: string,
156+
public async findActiveHostsByUserId(
157+
userId: bigint,
159158
returnDisabledHosts: boolean = false,
160159
returnHiddenHosts: boolean = false,
161160
): Promise<HostWithRawInbound[]> {
@@ -200,7 +199,7 @@ export class HostsRepository implements ICrud<HostsEntity> {
200199
)
201200
.$if(!returnDisabledHosts, (eb) => eb.where('hosts.isDisabled', '=', false))
202201
.$if(!returnHiddenHosts, (eb) => eb.where('hosts.isHidden', '=', false))
203-
.where('internalSquadMembers.userUuid', '=', getKyselyUuid(userUuid))
202+
.where('internalSquadMembers.userId', '=', userId)
204203
.selectAll('hosts')
205204

206205
.select([

src/modules/internal-squads/repositories/internal-squad.repository.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,13 @@ export class InternalSquadRepository implements ICrud<InternalSquadEntity> {
276276
}> {
277277
const result = await this.qb.kysely
278278
.insertInto('internalSquadMembers')
279-
.columns(['internalSquadUuid', 'userUuid'])
279+
.columns(['internalSquadUuid', 'userId'])
280280
.expression((eb) =>
281281
eb
282282
.selectFrom('users')
283283
.select([
284284
eb.val(getKyselyUuid(internalSquadUuid)).as('internalSquadUuid'),
285-
'uuid as userUuid',
285+
'tId',
286286
]),
287287
)
288288
.onConflict((oc) => oc.doNothing())

src/modules/subscription/subscription.service.ts

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
import type { Cache } from 'cache-manager';
2-
31
import dayjs from 'dayjs';
42
import pMap from 'p-map';
53
import _ from 'lodash';
64

7-
import { Inject, Injectable, Logger } from '@nestjs/common';
8-
import { CACHE_MANAGER } from '@nestjs/cache-manager';
95
import { EventEmitter2 } from '@nestjs/event-emitter';
6+
import { Injectable, Logger } from '@nestjs/common';
107
import { CommandBus, QueryBus } from '@nestjs/cqrs';
118
import { ConfigService } from '@nestjs/config';
129

@@ -47,7 +44,6 @@ import {
4744
SubscriptionWithConfigResponse,
4845
} from './models';
4946
import { getSubscriptionRefillDate, getSubscriptionUserInfo } from './utils/get-user-info.headers';
50-
import { HostWithRawInbound } from '../hosts/entities/host-with-inbound-tag.entity';
5147
import { GetHostsForUserQuery } from '../hosts/queries/get-hosts-for-user';
5248
import { ISubscriptionHeaders, IGetSubscriptionInfo } from './interfaces';
5349
import { GetAllSubscriptionsQueryDto } from './dto';
@@ -58,7 +54,6 @@ export class SubscriptionService {
5854
private readonly subPublicDomain: string;
5955

6056
constructor(
61-
@Inject(CACHE_MANAGER) private cacheManager: Cache,
6257
private readonly queryBus: QueryBus,
6358
private readonly configService: ConfigService,
6459
private readonly commandBus: CommandBus,
@@ -179,11 +174,9 @@ export class SubscriptionService {
179174
await this.checkAndUpsertHwidUserDevice(user.response, hwidHeaders);
180175
}
181176

182-
const hosts = await this.getHostsByUserUuid({
183-
userUuid: user.response.uuid,
184-
returnDisabledHosts: false,
185-
returnHiddenHosts: false,
186-
});
177+
const hosts = await this.queryBus.execute(
178+
new GetHostsForUserQuery(user.response.tId, false, false),
179+
);
187180

188181
if (!hosts.isOk || !hosts.response) {
189182
return new SubscriptionNotFoundResponse();
@@ -301,11 +294,9 @@ export class SubscriptionService {
301294
isHwidLimited = false;
302295
}
303296

304-
const hosts = await this.getHostsByUserUuid({
305-
userUuid: user.response.uuid,
306-
returnDisabledHosts: withDisabledHosts,
307-
returnHiddenHosts: true,
308-
});
297+
const hosts = await this.queryBus.execute(
298+
new GetHostsForUserQuery(user.response.tId, withDisabledHosts, true),
299+
);
309300

310301
if (!hosts.isOk || !hosts.response) {
311302
return {
@@ -381,11 +372,9 @@ export class SubscriptionService {
381372
return new SubscriptionNotFoundResponse();
382373
}
383374

384-
const hosts = await this.getHostsByUserUuid({
385-
userUuid: user.response.uuid,
386-
returnDisabledHosts: false,
387-
returnHiddenHosts: false,
388-
});
375+
const hosts = await this.queryBus.execute(
376+
new GetHostsForUserQuery(user.response.tId, false, false),
377+
);
389378

390379
if (!hosts.isOk || !hosts.response) {
391380
return new SubscriptionNotFoundResponse();
@@ -488,11 +477,9 @@ export class SubscriptionService {
488477
let ssConfLinks: Record<string, string> = {};
489478

490479
if (!settings.hwidSettings.enabled || authenticated) {
491-
const hostsResponse = await this.getHostsByUserUuid({
492-
userUuid: userEntity.uuid,
493-
returnDisabledHosts: false,
494-
returnHiddenHosts: false,
495-
});
480+
const hostsResponse = await this.queryBus.execute(
481+
new GetHostsForUserQuery(userEntity.tId, false, false),
482+
);
496483

497484
formattedHosts = await this.formatHostsService.generateFormattedHosts({
498485
subscriptionSettings: settings,
@@ -760,14 +747,6 @@ export class SubscriptionService {
760747
>(new GetUsersWithPaginationQuery(dto.start, dto.size));
761748
}
762749

763-
private async getHostsByUserUuid(
764-
dto: GetHostsForUserQuery,
765-
): Promise<ICommandResponse<HostWithRawInbound[]>> {
766-
return this.queryBus.execute<GetHostsForUserQuery, ICommandResponse<HostWithRawInbound[]>>(
767-
new GetHostsForUserQuery(dto.userUuid, dto.returnDisabledHosts, dto.returnHiddenHosts),
768-
);
769-
}
770-
771750
private async countHwidUserDevices(
772751
dto: CountUsersDevicesQuery,
773752
): Promise<ICommandResponse<number>> {

src/modules/users/entities/user-with-resolved-inbound.entity.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { ConfigProfileInboundEntity } from '@modules/config-profiles/entities';
22

33
export class UserWithResolvedInboundEntity {
4-
public userUuid: string;
54
public tId: bigint;
65
public trojanPassword: string;
76
public vlessUuid: string;
@@ -10,7 +9,6 @@ export class UserWithResolvedInboundEntity {
109
public inbounds: ConfigProfileInboundEntity[];
1110

1211
constructor(data: UserWithResolvedInboundEntity) {
13-
this.userUuid = data.userUuid;
1412
this.tId = data.tId;
1513
this.trojanPassword = data.trojanPassword;
1614
this.vlessUuid = data.vlessUuid;

0 commit comments

Comments
 (0)