Update configuration and documentation for syncrow.ae domain

This commit is contained in:
faris Aljohari
2025-07-17 20:56:35 -06:00
parent efa53da8c5
commit c0b95a8b4b
6 changed files with 45 additions and 28 deletions

View File

@ -5,12 +5,14 @@
Add these secrets to your GitHub repository (Settings > Secrets and variables > Actions): Add these secrets to your GitHub repository (Settings > Secrets and variables > Actions):
### AWS Credentials ### AWS Credentials
``` ```
AWS_ACCESS_KEY_ID=your-aws-access-key AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key AWS_SECRET_ACCESS_KEY=your-aws-secret-key
``` ```
### JWT Configuration (CRITICAL - Generate secure random strings) ### JWT Configuration (CRITICAL - Generate secure random strings)
``` ```
JWT_SECRET=your-super-secure-jwt-secret-key-here JWT_SECRET=your-super-secure-jwt-secret-key-here
JWT_SECRET_REFRESH=your-super-secure-refresh-secret-key-here JWT_SECRET_REFRESH=your-super-secure-refresh-secret-key-here
@ -18,12 +20,14 @@ SECRET_KEY=your-general-encryption-secret-key-here
``` ```
### Admin Configuration ### Admin Configuration
``` ```
SUPER_ADMIN_EMAIL=admin@syncrow.ae SUPER_ADMIN_EMAIL=admin@syncrow.ae
SUPER_ADMIN_PASSWORD=YourSecureAdminPassword123! SUPER_ADMIN_PASSWORD=YourSecureAdminPassword123!
``` ```
### Tuya IoT Configuration ### Tuya IoT Configuration
``` ```
TUYA_ACCESS_ID=your-tuya-access-id TUYA_ACCESS_ID=your-tuya-access-id
TUYA_ACCESS_KEY=your-tuya-access-key TUYA_ACCESS_KEY=your-tuya-access-key
@ -31,6 +35,7 @@ TRUN_ON_TUYA_SOCKET=true-or-false
``` ```
### Firebase Configuration ### Firebase Configuration
``` ```
FIREBASE_API_KEY=your-firebase-api-key FIREBASE_API_KEY=your-firebase-api-key
FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
@ -43,18 +48,21 @@ FIREBASE_DATABASE_URL=https://your-project.firebaseio.com
``` ```
### Google OAuth ### Google OAuth
``` ```
GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret GOOGLE_CLIENT_SECRET=your-google-client-secret
``` ```
### OneSignal Push Notifications ### OneSignal Push Notifications
``` ```
ONESIGNAL_APP_ID=your-onesignal-app-id ONESIGNAL_APP_ID=your-onesignal-app-id
ONESIGNAL_API_KEY=your-onesignal-api-key ONESIGNAL_API_KEY=your-onesignal-api-key
``` ```
### Email Configuration (SMTP) ### Email Configuration (SMTP)
``` ```
SMTP_HOST=your-smtp-host SMTP_HOST=your-smtp-host
SMTP_USER=your-smtp-username SMTP_USER=your-smtp-username
@ -62,6 +70,7 @@ SMTP_PASSWORD=your-smtp-password
``` ```
### Mailtrap Configuration ### Mailtrap Configuration
``` ```
MAILTRAP_API_TOKEN=your-mailtrap-api-token MAILTRAP_API_TOKEN=your-mailtrap-api-token
MAILTRAP_ENABLE_TEMPLATE_UUID=template-uuid MAILTRAP_ENABLE_TEMPLATE_UUID=template-uuid
@ -72,6 +81,7 @@ MAILTRAP_EDIT_USER_TEMPLATE_UUID=template-uuid
``` ```
### Optional Services (leave empty if not used) ### Optional Services (leave empty if not used)
``` ```
AZURE_REDIS_CONNECTIONSTRING=your-redis-connection-string AZURE_REDIS_CONNECTIONSTRING=your-redis-connection-string
DOPPLER_PROJECT=your-doppler-project DOPPLER_PROJECT=your-doppler-project
@ -101,7 +111,7 @@ DOCKER_REGISTRY_SERVER_PASSWORD=your-registry-password
4. **Test Deployment** 4. **Test Deployment**
- Push to master/main branch - Push to master/main branch
- Check GitHub Actions tab for deployment status - Check GitHub Actions tab for deployment status
- Verify API is accessible at https://api.syncrow.me - Verify API is accessible at https://api.syncos.syncrow.ae
## Security Notes ## Security Notes

View File

@ -1,17 +1,19 @@
# Backend # Backend
## Overview ## Overview
This is the backend for an IoT application built using NestJS. It interfaces with the Tuya IoT cloud platform to manage homes, rooms, devices, ...etc. This is the backend for an IoT application built using NestJS. It interfaces with the Tuya IoT cloud platform to manage homes, rooms, devices, ...etc.
This is the backend APIs project, developed with NestJS for Syncrow IOT Project. This is the backend APIs project, developed with NestJS for Syncrow IOT Project.
## Database Model ## Database Model
The database uses PostgreSQL and TypeORM. Below is an entity relationship diagram: The database uses PostgreSQL and TypeORM. Below is an entity relationship diagram:
The main entities are: The main entities are:
User - Stores user account information User - Stores user account information
Home - Represents a home/space Home - Represents a home/space
Room - Represents a room/sub-space Room - Represents a room/sub-space
Device - Represents a connected device Device - Represents a connected device
Product - Stores metadata about device products Product - Stores metadata about device products
Other Entities - sessions, OTPs, etc. Other Entities - sessions, OTPs, etc.
@ -19,10 +21,11 @@ Other Entities - sessions, OTPs, etc.
The entities have a one-to-many relationship - a user has multiple homes, a home has multiple rooms, and a room has multiple devices. The entities have a one-to-many relationship - a user has multiple homes, a home has multiple rooms, and a room has multiple devices.
## Architecture ## Architecture
The application is deployed on Azure App Service using Docker containers. There are separate deployment slots for development, staging, and production environments. The application is deployed on Azure App Service using Docker containers. There are separate deployment slots for development, staging, and production environments.
## Installation ## Installation
First, ensure that you have Node.js `v20.11` or newer (LTS ONLY) installed on your system. First, ensure that you have Node.js `v20.11` or newer (LTS ONLY) installed on your system.
To install the project dependencies, run the following command in the project root directory: To install the project dependencies, run the following command in the project root directory:
@ -61,8 +64,8 @@ $ npm run test:cov
![Syncrow ERD Digram](https://github.com/SyncrowIOT/backend/assets/83524184/94273a2b-625c-4a34-9cd4-fb14415ce884) ![Syncrow ERD Digram](https://github.com/SyncrowIOT/backend/assets/83524184/94273a2b-625c-4a34-9cd4-fb14415ce884)
## Architecture ## Architecture
+----------------------------------+ +----------------------------------+
| | | |
| Applications | | Applications |
@ -120,8 +123,8 @@ $ npm run test:cov
• After code changes: build Docker image, push to ECR, force ECS deployment • After code changes: build Docker image, push to ECR, force ECS deployment
• Database seeding happens automatically on first deployment with DB_SYNC=true • Database seeding happens automatically on first deployment with DB_SYNC=true
• Admin credentials: admin@syncrow.ae / YourSecureAdminPassword123! • Admin credentials: admin@syncrow.ae / YourSecureAdminPassword123!
• Production API: https://api.syncrow.me • Production API: https://api.syncos.syncrow.ae
• Health check: https://api.syncrow.me/health • Health check: https://api.syncos.syncrow.ae/health
## GitHub Actions Deployment ## GitHub Actions Deployment

View File

@ -21,5 +21,9 @@
"hosted-zone:account=482311766496:domainName=syncrow.me:region=me-central-1": { "hosted-zone:account=482311766496:domainName=syncrow.me:region=me-central-1": {
"Id": "/hostedzone/Z02085662NLJECF4DGJV3", "Id": "/hostedzone/Z02085662NLJECF4DGJV3",
"Name": "syncrow.me." "Name": "syncrow.me."
},
"hosted-zone:account=482311766496:domainName=syncrow.ae:region=me-central-1": {
"Id": "/hostedzone/Z01153152LRHQTA1370P4",
"Name": "syncrow.ae."
} }
} }

View File

@ -12,5 +12,5 @@ new BackendStack(app, 'SyncrowBackendStack', {
}, },
databaseName: 'postgres', databaseName: 'postgres',
certificateArn: certificateArn:
'arn:aws:acm:me-central-1:482311766496:certificate/bea1e2ae-84a1-414e-8dbf-4599397e7ed0', 'arn:aws:acm:me-central-1:482311766496:certificate/423b343e-402b-4978-89bd-cda25f7a8873',
}); });

View File

@ -168,7 +168,7 @@ export class BackendStack extends cdk.Stack {
props.certificateArn, props.certificateArn,
) )
: new acm.Certificate(this, 'ApiCertificate', { : new acm.Certificate(this, 'ApiCertificate', {
domainName: 'api.syncrow.me', domainName: 'api.syncos.syncrow.ae',
validation: acm.CertificateValidation.fromDns(), validation: acm.CertificateValidation.fromDns(),
}); });
@ -182,9 +182,9 @@ export class BackendStack extends cdk.Stack {
memoryLimitMiB: 1024, memoryLimitMiB: 1024,
cpu: 512, cpu: 512,
desiredCount: 2, desiredCount: 2,
domainName: 'api.syncrow.me', domainName: 'api.syncos.syncrow.ae',
domainZone: route53.HostedZone.fromLookup(this, 'SyncrowZone', { domainZone: route53.HostedZone.fromLookup(this, 'SyncrowZone', {
domainName: 'syncrow.me', domainName: 'syncrow.ae',
}), }),
certificate: apiCertificate, certificate: apiCertificate,
protocol: elbv2.ApplicationProtocol.HTTPS, protocol: elbv2.ApplicationProtocol.HTTPS,
@ -356,7 +356,7 @@ export class BackendStack extends cdk.Stack {
// Grant ECS task access to RDS credentials // Grant ECS task access to RDS credentials
dbSecret.grantRead(fargateService.taskDefinition.taskRole); dbSecret.grantRead(fargateService.taskDefinition.taskRole);
this.apiUrl = 'https://api.syncrow.me'; this.apiUrl = 'https://api.syncos.syncrow.ae';
this.databaseEndpoint = dbCluster.clusterEndpoint.hostname; this.databaseEndpoint = dbCluster.clusterEndpoint.hostname;
// Outputs // Outputs

30
package-lock.json generated
View File

@ -852,7 +852,7 @@
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "0.3.9" "@jridgewell/trace-mapping": "0.3.9"
@ -865,7 +865,7 @@
"version": "0.3.9", "version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/resolve-uri": "^3.0.3",
@ -3035,28 +3035,28 @@
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tsconfig/node12": { "node_modules/@tsconfig/node12": {
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tsconfig/node14": { "node_modules/@tsconfig/node14": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tsconfig/node16": { "node_modules/@tsconfig/node16": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tuya/tuya-connector-nodejs": { "node_modules/@tuya/tuya-connector-nodejs": {
@ -3853,7 +3853,7 @@
"version": "8.3.4", "version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"acorn": "^8.11.0" "acorn": "^8.11.0"
@ -4040,7 +4040,7 @@
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/argon2": { "node_modules/argon2": {
@ -5910,7 +5910,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
@ -6194,7 +6194,7 @@
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true, "devOptional": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
@ -10286,7 +10286,7 @@
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true, "devOptional": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/makeerror": { "node_modules/makeerror": {
@ -13405,7 +13405,7 @@
"version": "10.9.2", "version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "^0.8.0", "@cspotcode/source-map-support": "^0.8.0",
@ -13816,7 +13816,7 @@
"version": "5.7.3", "version": "5.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"dev": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -13962,7 +13962,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
@ -14540,7 +14540,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"