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
| File | Purpose |
|---|---|
package.json | Dependencies and scripts |
tsconfig.json | TypeScript configuration |
nest-cli.json | NestJS CLI configuration |
.eslintrc.js | ESLint rules |
.prettierrc | Prettier formatting |
docker-compose.yml | Container orchestration |
Dockerfile | Container image build |
Makefile | Development commands |
Next Steps
- Development Guide - Local setup and workflows
- Database Schema - Detailed entity documentation
- Testing Guide - Test structure and commands