Skip to main content

Project Structure

Overview of the AsaHome Cloud source code organization.

Directory Layout

src/
├── api/ # API key and rate limiting
│ └── entities/
│ └── api-key.entity.ts

├── app.controller.ts # Root controller (health check)
├── app.module.ts # Main application module
├── app.service.ts # Root service

├── audit/ # Audit logging
│ └── entities/
│ └── audit-log.entity.ts

├── auth/ # Authentication module
│ ├── auth.controller.ts # Auth endpoints
│ ├── auth.module.ts # Module configuration
│ ├── auth.service.ts # Auth business logic
│ ├── decorators/ # Custom decorators
│ │ ├── public.decorator.ts
│ │ └── allow-internal-api-key.decorator.ts
│ ├── dto/ # Data transfer objects
│ │ ├── login.dto.ts
│ │ ├── refresh-token.dto.ts
│ │ └── sync-customer.dto.ts
│ ├── entities/ # Auth-related entities
│ │ ├── refresh-token.entity.ts
│ │ ├── login-attempt.entity.ts
│ │ └── oauth-account.entity.ts
│ ├── guards/ # Auth guards
│ │ ├── jwt-auth.guard.ts
│ │ └── internal-api-key.guard.ts
│ └── strategies/ # Passport strategies
│ ├── jwt.strategy.ts
│ └── local.strategy.ts

├── billing/ # Subscription and payments
│ └── entities/
│ ├── subscription.entity.ts
│ └── payment.entity.ts

├── config/ # Configuration
│ ├── data-source.ts # TypeORM data source
│ └── typeorm.config.ts # TypeORM module config

├── customers/ # Customer management (Laravel sync)
│ ├── customers.controller.ts
│ ├── customers.module.ts
│ ├── customers.service.ts
│ └── dto/
│ └── sync-customer.dto.ts

├── devices/ # Device management
│ ├── devices.controller.ts
│ ├── devices.module.ts
│ ├── devices.service.ts
│ ├── dto/
│ │ ├── register-device.dto.ts
│ │ ├── update-device.dto.ts
│ │ └── link-device.dto.ts
│ └── entities/
│ ├── device.entity.ts
│ └── device-user.entity.ts

├── homes/ # Home management
│ └── entities/
│ ├── home.entity.ts
│ └── home-member.entity.ts

├── main.ts # Application entry point

├── migrations/ # Database migrations
│ ├── 1700000000000-InitialSchema.ts
│ ├── 1700000000001-AddDevices.ts
│ └── ...

├── notifications/ # Push notifications
│ └── entities/
│ └── push-token.entity.ts

├── os/ # OS instance tracking
│ └── entities/
│ └── os-instance.entity.ts

├── system/ # System settings
│ └── entities/
│ ├── feature-flag.entity.ts
│ └── system-setting.entity.ts

├── tunnels/ # Tunnel session tracking
│ └── entities/
│ └── tunnel-session.entity.ts

├── users/ # User management
│ ├── entities/
│ │ ├── user.entity.ts
│ │ ├── user-profile.entity.ts
│ │ └── client-device.entity.ts
│ ├── users.controller.ts
│ ├── users.module.ts
│ └── users.service.ts

└── websocket/ # WebSocket gateway
├── guards/
│ └── ws-jwt.guard.ts
├── websocket.gateway.ts
└── websocket.module.ts

Module Architecture

Each feature follows NestJS module conventions:

Module Example: Devices

// devices.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([Device, DeviceUser]),
],
controllers: [DevicesController],
providers: [DevicesService],
exports: [DevicesService],
})
export class DevicesModule {}

Key Files Explained

Entry Point

main.ts - Application bootstrap:

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Global prefix
app.setGlobalPrefix('api/v1');

// Security
app.use(helmet());
app.enableCors({
origin: process.env.CORS_ORIGINS?.split(','),
credentials: true,
});

// Validation
app.useGlobalPipes(new ValidationPipe({
whitelist: true,
transform: true,
}));

// Swagger
const config = new DocumentBuilder()
.setTitle('AsaHome Cloud API')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api/v1/docs', app, document);

await app.listen(process.env.PORT || 3000);
}

App Module

app.module.ts - Root module importing all features:

@Module({
imports: [
// Configuration
ConfigModule.forRoot({ isGlobal: true }),

// Database
TypeOrmModule.forRootAsync({
useClass: TypeOrmConfigService,
}),

// Rate limiting
ThrottlerModule.forRoot({
ttl: 60,
limit: 100,
}),

// Feature modules
AuthModule,
UsersModule,
DevicesModule,
CustomersModule,
WebSocketModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

Database Configuration

config/data-source.ts - TypeORM data source for migrations:

export const AppDataSource = new DataSource({
type: 'postgres',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: ['src/**/*.entity.ts'],
migrations: ['src/migrations/*.ts'],
synchronize: false,
});

WebSocket Gateway

websocket/websocket.gateway.ts - Real-time tunnel:

@WebSocketGateway({
namespace: '/tunnel',
cors: true,
})
export class TunnelGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer()
server: Server;

private deviceSockets = new Map<string, Socket>();
private userSockets = new Map<string, Socket>();

handleConnection(client: Socket) {
// Authenticate and register socket
}

@SubscribeMessage('tunnel:message')
handleTunnelMessage(
@ConnectedSocket() client: Socket,
@MessageBody() data: TunnelMessageDto,
) {
// Route message to device
}
}

Entity Relationships

Configuration Files

FilePurpose
package.jsonDependencies and scripts
tsconfig.jsonTypeScript configuration
nest-cli.jsonNestJS CLI configuration
.eslintrc.jsESLint rules
.prettierrcPrettier formatting
docker-compose.ymlContainer orchestration
DockerfileContainer image build
MakefileDevelopment commands

Next Steps