diff --git a/docs/how-to-add-notifier.md b/docs/how-to-add-notifier.md new file mode 100644 index 0000000..8f836e1 --- /dev/null +++ b/docs/how-to-add-notifier.md @@ -0,0 +1,45 @@ +# How to add new notifier to Postgresus (Discord, Slack, Telegram, Email, Webhook, etc.) + +## Backend part + +1. Create new model in `backend/internal/features/notifiers/models/{notifier_name}/` folder. Implement `NotificationSender` interface from parent folder. + - The model should implement `Send(logger *slog.Logger, heading string, message string) error` and `Validate() error` methods + - Use UUID primary key as `NotifierID` that references the main notifiers table + +2. Add new notifier type to `backend/internal/features/notifiers/enums.go` in the `NotifierType` constants. + +3. Update the main `Notifier` model in `backend/internal/features/notifiers/model.go`: + - Add new notifier field with GORM foreign key relation + - Update `getSpecificNotifier()` method to handle the new type + - Update `Send()` method to route to the new notifier + +4. If you need to add some .env variables to test, add them in `backend/internal/config/config.go` (so we can use it in tests) + +5. If you need some Docker container to test, add it to `backend/docker-compose.yml.example`. For sensitive data - keep it blank. + +6. If you need some sensitive envs to test in pipeline, message @rostislav_dugin so I can add it to GitHub Actions. For example, API keys or credentials. + +7. Create new migration in `backend/migrations` folder: + - Create table with `notifier_id` as UUID primary key + - Add foreign key constraint to `notifiers` table with CASCADE DELETE + - Look at existing notifier migrations for reference + +8. Make sure that all tests are passing. + +## Frontend part + +If you are able to develop only backend - it's fine, message @rostislav_dugin so I can complete UI part. + +1. Add models and validator to `frontend/src/entity/notifiers/models/{notifier_name}/` folder and update `index.ts` file to include new model exports. + +2. Upload an SVG icon to `public/icons/notifiers/`, update `src/entity/notifiers/models/getNotifierLogoFromType.ts` to return new icon path, update `src/entity/notifiers/models/NotifierType.ts` to include new type, and update `src/entity/notifiers/models/getNotifierNameFromType.ts` to return new name. + +3. Add UI components to manage your notifier: + - `src/features/notifiers/ui/edit/notifiers/Edit{NotifierName}Component.tsx` (for editing) + - `src/features/notifiers/ui/show/notifier/Show{NotifierName}Component.tsx` (for display) + +4. Update main components to handle the new notifier type: + - `EditNotifierComponent.tsx` - add import, validation function, and component rendering + - `ShowNotifierComponent.tsx` - add import and component rendering + +5. Make sure everything is working as expected. diff --git a/docs/how-to-add-storage.md b/docs/how-to-add-storage.md new file mode 100644 index 0000000..e26ee5b --- /dev/null +++ b/docs/how-to-add-storage.md @@ -0,0 +1,51 @@ +# How to add new storage to Postgresus (S3, FTP, Google Drive, NAS, etc.) + +## Backend part + +1. Create new model in `backend/internal/features/storages/models/{storage_name}/` folder. Implement `StorageFileSaver` interface from parent folder. + - The model should implement `SaveFile(logger *slog.Logger, fileID uuid.UUID, file io.Reader) error`, `GetFile(fileID uuid.UUID) (io.ReadCloser, error)`, `DeleteFile(fileID uuid.UUID) error`, `Validate() error`, and `TestConnection() error` methods + - Use UUID primary key as `StorageID` that references the main storages table + - Add `TableName() string` method to return the proper table name + +2. Add new storage type to `backend/internal/features/storages/enums.go` in the `StorageType` constants. + +3. Update the main `Storage` model in `backend/internal/features/storages/model.go`: + - Add new storage field with GORM foreign key relation + - Update `getSpecificStorage()` method to handle the new type + - Update `SaveFile()`, `GetFile()`, and `DeleteFile()` methods to route to the new storage + - Update `Validate()` method to include new storage validation + +4. If you need to add some .env variables to test, add them in `backend/internal/config/config.go` (so we can use it in tests) + +5. If you need some Docker container to test, add it to `backend/docker-compose.yml.example`. For sensitive data - keep it blank. + +6. If you need some sensitive envs to test in pipeline, message @rostislav_dugin so I can add it to GitHub Actions. For example, Google Drive envs or FTP credentials. + +7. Create new migration in `backend/migrations` folder: + - Create table with `storage_id` as UUID primary key + - Add foreign key constraint to `storages` table with CASCADE DELETE + - Look at existing storage migrations for reference + +8. Update tests in `backend/internal/features/storages/model_test.go` to test new storage + +9. Make sure that all tests are passing. + +## Frontend part + +If you are able to develop only backend - it's fine, message @rostislav_dugin so I can complete UI part. + +1. Add models and api to `frontend/src/entity/storages/models/` folder and update `index.ts` file to include new model exports. + - Create TypeScript interface for your storage model + - Add validation function if needed + +2. Upload an SVG icon to `public/icons/storages/`, update `src/entity/storages/models/getStorageLogoFromType.ts` to return new icon path, update `src/entity/storages/models/StorageType.ts` to include new type, and update `src/entity/storages/models/getStorageNameFromType.ts` to return new name. + +3. Add UI components to manage your storage: + - `src/features/storages/ui/edit/storages/Edit{StorageName}Component.tsx` (for editing) + - `src/features/storages/ui/show/storages/Show{StorageName}Component.tsx` (for display) + +4. Update main components to handle the new storage type: + - `EditStorageComponent.tsx` - add import and component rendering + - `ShowStorageComponent.tsx` - add import and component rendering + +5. Make sure everything is working as expected. diff --git a/frontend/src/entity/notifiers/models/getNotifierNameFromType.ts b/frontend/src/entity/notifiers/models/getNotifierNameFromType.ts index 4597f50..f4952e6 100644 --- a/frontend/src/entity/notifiers/models/getNotifierNameFromType.ts +++ b/frontend/src/entity/notifiers/models/getNotifierNameFromType.ts @@ -10,6 +10,8 @@ export const getNotifierNameFromType = (type: NotifierType) => { return 'Webhook'; case NotifierType.SLACK: return 'Slack'; + case NotifierType.DISCORD: + return 'Discord'; default: return ''; }