Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace shard db connection in favour of tenant #469

Merged
merged 2 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Assumping you have a local development setup running, run
```sh
docker exec -it backend-dev bash
php artisan erd:generate micro_power_manager --excludes=plugins --file=central_database.sql
php artisan erd:generate shard --path=/database/migrations/micropowermanager --excludes=companies,company_databases,company_jobs,database_proxies --file=tenant_database.sql
php artisan erd:generate tenant --path=/database/migrations/micropowermanager --excludes=companies,company_databases,company_jobs,database_proxies --file=tenant_database.sql
php artisan export
```

Expand Down
21 changes: 10 additions & 11 deletions docs/development/multitenancy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Sharding is a technique employed to partition a large database into smaller, mor
known as data shards. In the context of Micropower Manager, sharding is integral to the implementation of Software as a
Service (SaaS) functionality.

### Shard Representation
### Tenant Representation

Each shard in Micropower Manager represents an individual company leveraging the platform for their Customer
Each tenant in Micropower Manager represents an individual company leveraging the platform for their Customer
Relationship Management (CRM) needs.

### Central Database - "micro_power_manager"
Expand All @@ -35,37 +35,36 @@ Upon successful registration, when a user associated with a particular company l
database connection for their session is dynamically altered. This ensures that the user gains access to and interacts
with data exclusive to their company, providing a personalized and secure experience within the application.

## Sharding Specific Migration Commands
## Tenant Specific Migration Commands

- **Creating Migration File:**
- **Creating Migration File (core):**
When creating a migration file, you need to use the following command:

```bash
docker exec -it backend-dev bash
php artisan migrator:create {migration-name}
php artisan make:migration {migration-name}
```

This command creates a migration file in Micropower Manager's core migration files location: `src/backend/database/migrations/micropowermanager`

After creating the migration file, you can shift it to other company databases using the following command:
- **Creating Migration File (tenant):**
To create a migration file for tenant database(s) use the following command:

```bash
docker exec -it backend-dev bash
php artisan migrator:copy
php artisan make:migration-tenant {migration-name}
```

This command syncs the migration files in the core migration folder for other company migrations.

To migrate the database, use the following command:

```bash
docker exec -it backend-dev bash
php artisan migrator:migrate
php artisan migrate
```

Alternatively, you can migrate the database for a specific company using the following command:

```bash
docker exec -it backend-dev bash
php shard:migrate {company_id} {--force}
php migrate-tenant {company_id} {--force}
```
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/BackupTenantDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class BackupTenantDatabase extends AbstractSharedCommand {
protected $description = 'Run the backup for provided tenant database(s)';

public function handle() {
$databaseName = config('database.connections.shard');
$databaseName = config('database.connections.tenant');
$this->info('Starting backup for tenant databases');
dump($this->arguments());
config(['database.connections.mysql' => $databaseName]);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenant.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenant extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantFresh.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantFresh extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:fresh', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantInstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantInstall extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:install', [
'--database' => 'shard',
'--database' => 'tenant',
]);
}
}
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantRefresh.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantRefresh extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:refresh', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantReset.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantReset extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:reset', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantRollback.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantRollback extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:rollback', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Console/Commands/MigrateTenantStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MigrateTenantStatus extends AbstractSharedCommand {
public function handle() {
$this->call('optimize:clear');
$this->call('migrate:status', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public function handle() {
}
}
});
DB::connection('shard')->table('meters')->truncate();
DB::connection('shard')->table('meter_tariffs')->truncate();
DB::connection('tenant')->table('meters')->truncate();
DB::connection('tenant')->table('meter_tariffs')->truncate();

ConnectionGroup::query()->whereIn('id', [2, 3])->get()->map(function ($q) {
$q->delete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public function __construct(private AppliancePaymentService $appliancePaymentSer

public function store(AssetPerson $appliancePerson, Request $request): ApiResource {
try {
DB::connection('shard')->beginTransaction();
DB::connection('tenant')->beginTransaction();
$this->appliancePaymentService->getPaymentForAppliance($request, $appliancePerson);
DB::connection('shard')->commit();
DB::connection('tenant')->commit();

return ApiResource::make($appliancePerson);
} catch (\Exception $e) {
DB::connection('shard')->rollBack();
DB::connection('tenant')->rollBack();
throw new \Exception($e->getMessage());
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/backend/app/Http/Controllers/AssetPersonController.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function store(
$installmentType = $request->input('rate_type');
$points = $request->input('points');

DB::connection('shard')->beginTransaction();
DB::connection('tenant')->beginTransaction();

$appliancePerson = $this->assetPersonService->make([
'asset_id' => $applianceId,
Expand Down Expand Up @@ -128,11 +128,11 @@ public function store(
]
);
}
DB::connection('shard')->commit();
DB::connection('tenant')->commit();

return ApiResource::make($appliancePerson);
} catch (\Exception $e) {
DB::connection('shard')->rollBack();
DB::connection('tenant')->rollBack();
throw new \Exception($e->getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public function __construct(private CustomerRegistrationAppService $customerRegi

public function store(AndroidAppRequest $request) {
try {
DB::connection('shard')->beginTransaction();
DB::connection('tenant')->beginTransaction();
$person = $this->customerRegistrationAppService->createCustomer($request);
DB::connection('shard')->commit();
DB::connection('tenant')->commit();

return ApiResource::make($person)->response()->setStatusCode(201);
} catch (\Exception $e) {
DB::connection('shard')->rollBack();
DB::connection('tenant')->rollBack();
Log::critical('Error while adding new Customer', ['message' => $e->getMessage()]);
throw new \Exception($e->getMessage());
}
Expand Down
6 changes: 3 additions & 3 deletions src/backend/app/Http/Controllers/PersonController.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function store(PersonRequest $request): JsonResponse {
$addressData = $this->addressService->createAddressDataFromRequest($request);
$personData = $this->personService->createPersonDataFromRequest($request);
$miniGridId = $request->input('mini_grid_id');
DB::connection('shard')->beginTransaction();
DB::connection('tenant')->beginTransaction();
if ($this->personService->isMaintenancePerson($customerType)) {
$person = $this->personService->createMaintenancePerson($personData);
$maintenanceUserData = [
Expand All @@ -100,11 +100,11 @@ public function store(PersonRequest $request): JsonResponse {
$this->personAddressService->setAssigned($address);
$this->personAddressService->assign();
$this->addressService->save($address);
DB::connection('shard')->commit();
DB::connection('tenant')->commit();

return ApiResource::make($person)->response()->setStatusCode(201);
} catch (\Exception $e) {
DB::connection('shard')->rollBack();
DB::connection('tenant')->rollBack();
throw new \Exception($e->getMessage());
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/backend/app/Http/Requests/MaintenanceRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public function rules() {
'birth_date' => 'sometimes|date_format:"Y-m-d',
'sex' => 'sometimes|in:male,female',
'education' => 'sometimes|min:3',
'city_id' => 'sometimes|exists:shard.cities,id',
'city_id' => 'sometimes|exists:tenant.cities,id',
'street' => 'sometimes|string|min:3',
'email' => 'sometimes|email',
'phone' => 'required|min:11|regex:(^\+)|numeric',
'nationality' => 'sometimes|exists:shard.countries,country_code',
'nationality' => 'sometimes|exists:tenant.countries,country_code',
];
}

Expand Down
6 changes: 3 additions & 3 deletions src/backend/app/Http/Requests/StoreEBikeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public function authorize(): bool {
*/
public function rules() {
return [
'serial_number' => 'required|min:8|max:15|unique:shard.devices,device_serial',
'manufacturer_id' => 'required|exists:shard.manufacturers,id',
'asset_id' => 'required|exists:shard.assets,id',
'serial_number' => 'required|min:8|max:15|unique:tenant.devices,device_serial',
'manufacturer_id' => 'required|exists:tenant.manufacturers,id',
'asset_id' => 'required|exists:tenant.assets,id',
];
}
}
6 changes: 3 additions & 3 deletions src/backend/app/Http/Requests/StoreSolarHomeSystemRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public function authorize(): bool {
*/
public function rules() {
return [
'serial_number' => 'required|min:8|max:11|unique:shard.devices,device_serial',
'manufacturer_id' => 'required|exists:shard.manufacturers,id',
'asset_id' => 'required|exists:shard.assets,id',
'serial_number' => 'required|min:8|max:11|unique:tenant.devices,device_serial',
'manufacturer_id' => 'required|exists:tenant.manufacturers,id',
'asset_id' => 'required|exists:tenant.assets,id',
];
}
}
2 changes: 1 addition & 1 deletion src/backend/app/Models/Agent.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Agent extends Authenticatable implements JWTSubject {
public const RELATION_NAME = 'agent';

public function __construct(array $attributes = []) {
$this->setConnection('shard');
$this->setConnection('tenant');
parent::__construct($attributes);
}

Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Models/Base/BaseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ abstract class BaseModel extends Model {

public function __construct(array $attributes = []) {
parent::__construct($attributes);
$this->setConnection('shard');
$this->setConnection('tenant');
}
}
4 changes: 2 additions & 2 deletions src/backend/app/Models/ConnectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public function meterParametersCount($till) {
}

public function numberOfConnections(): Collection {
return DB::connection('shard')->table('meter_parameters')
->select(DB::connection('shard')->raw('connection_type_id, count(id) as total'))
return DB::connection('tenant')->table('meter_parameters')
->select(DB::connection('tenant')->raw('connection_type_id, count(id) as total'))
->groupBy('connection_type_id')
->get();
}
Expand Down
4 changes: 2 additions & 2 deletions src/backend/app/Models/Meter/Meter.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class Meter extends BaseModel {
protected $guarded = [];
public static $rules = [
'serial_number' => 'required|min:1|unique:meters',
'meter_type_id' => 'exists:shard.meter_types,id',
'manufacturer_id' => 'exists:shard.manufacturers,id',
'meter_type_id' => 'exists:tenant.meter_types,id',
'manufacturer_id' => 'exists:tenant.manufacturers,id',
];

public function meterType(): BelongsTo {
Expand Down
8 changes: 4 additions & 4 deletions src/backend/app/Models/PaymentHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function getPaymentFlow(string $payer_type, int $payer_id, int $year) {
$sql = 'SELECT sum(amount) as amount, MONTH(created_at) as month from payment_histories where'.
' payer_id=:payer_id and payer_type=:payer_type and '.
'YEAR(created_at)=:year group by MONTH(created_at) order by MONTH(created_at) ';
$sth = DB::connection('shard')->getPdo()->prepare($sql);
$sth = DB::connection('tenant')->getPdo()->prepare($sql);
$sth->bindValue(':payer_id', $payer_id, \PDO::PARAM_INT);
$sth->bindValue(':payer_type', $payer_type, \PDO::PARAM_STR);
$sth->bindValue(':year', $year);
Expand All @@ -84,15 +84,15 @@ public function getOverview($begin, $end) {
$sql = 'SELECT sum(amount) as total, DATE_FORMAT(created_at, "%Y-%m-%d")'.
' as dato from payment_histories where DATE(created_at) >= DATE(\''.$begin.'\') '.
'and DATE(created_at)<= DATE(\''.$end.'\') group by dato';
$sth = DB::connection('shard')->getPdo()->prepare($sql);
$sth = DB::connection('tenant')->getPdo()->prepare($sql);
$sth->execute();
$results = $sth->fetchAll(\PDO::FETCH_ASSOC);

return $results;
}

private function executeSqlCommand(string $sql, $payer_id, $agent_id, $payer_type) {
$sth = DB::connection('shard')->getPdo()->prepare($sql);
$sth = DB::connection('tenant')->getPdo()->prepare($sql);
if ($payer_id) {
$sth->bindValue(':payer_id', $payer_id, \PDO::PARAM_INT);
}
Expand All @@ -110,7 +110,7 @@ public function findCustomersPaidInRange(
CarbonImmutable $startDate,
CarbonImmutable $endDate,
): Collection {
return DB::connection('shard')->table($this->getTable())
return DB::connection('tenant')->table($this->getTable())
->select('payer_id as customer_id')
->whereDate('created_at', '>=', $startDate)
->whereDate('created_at', '<=', $endDate)
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class User extends Authenticatable implements JWTSubject {
public const COL_COMPANY_ID = 'company_id';

public function __construct(array $attributes = []) {
$this->setConnection('shard');
$this->setConnection('tenant');

parent::__construct($attributes);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Services/CompanyDatabaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function create(array $data): CompanyDatabase {
$company_id,
function () {
Artisan::call('migrate', [
'--database' => 'shard',
'--database' => 'tenant',
'--path' => '/database/migrations/micropowermanager',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/app/Services/SessionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ private function checkDatabaseName($databaseName): bool {
}

public function getAuthenticatedUserDatabaseName(): string {
return config()->get('database.connections.shard.database');
return config()->get('database.connections.tenant.database');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function insertFromCsv() {
$tariff
) {
try {
DB::connection('shard')->beginTransaction();
DB::connection('tenant')->beginTransaction();
$row['cluster_id'] = $cluster->id;
$row['mini_grid_id'] = $miniGrid->id;
$row['tariff_id'] = $tariff->id;
Expand Down Expand Up @@ -116,10 +116,10 @@ public function insertFromCsv() {

$appliancePerson = $this->createRecordFromCsv($row, AppliancePersonService::class);
$this->checkRecordWasRecentlyCreated($appliancePerson, 'appliance_person');
DB::connection('shard')->commit();
DB::connection('tenant')->commit();
} catch (\Exception $exception) {
Log::error($exception->getMessage());
DB::connection('shard')->rollBack();
DB::connection('tenant')->rollBack();
throw $exception;
}
});
Expand Down
Loading
Loading