6.4 KiB
		
	
	
	
	
			
		
		
	
	Server code
Database model typing
Sequelize models contain optional fields corresponding to table joins.
For example, VideoModel has a VideoChannel?: VideoChannelModel field. It can be filled if the SQL query joined with the videoChannel table or empty if not.
It can be difficult in TypeScript to understand if a function argument expects associations to be filled or not.
To improve clarity and reduce bugs, PeerTube defines multiple versions of a database model depending on its associations in server/core/types/models/.
These models start with M and by default do not include any association. MVideo for example corresponds to VideoModel without any association, where VideoChannel attribute doesn't exist. On the other hand, MVideoWithChannel is a MVideo that has a VideoChannel field. This way, a function that accepts video: MVideoWithChannel argument expects a video with channel populated. Main PeerTube code should never use ...Model (VideoModel) database type, but always M... instead (MVideo, MVideoChannel etc).
Add a new feature walkthrough
Here's a list of all the parts of the server to update if you want to add a new feature (new API REST endpoints for example) to the PeerTube server. Some of these may be optional (for example your new endpoint may not need to send notifications) but this guide tries to be exhaustive.
- Configuration:
- Add you new configuration key in config/default.yamlandconfig/production.yaml
- If you configuration needs to be different in dev or tests environments, also update config/dev.yamlandconfig/test.yaml
- Load your configuration in server/core/initializers/config.ts
- Check new configuration keys are set in server/core/initializers/checker-before-init.ts
- You can also ensure configuration consistency in server/core/initializers/checker-after-init.ts
- If you want your configuration to be available in the client:
- Add your field in packages/models/src/server/core/server-config.model.ts
- Update server/core/lib/server-config-manager.tsto include your new configuration
 
- Add your field in 
- If you want your configuration to be updatable by the web admin in the client:
- Add your field in packages/models/src/server/core/custom-config.model.ts
- Add the configuration to the config object in the server/core/controllers/api/config.tscontroller
 
- Add your field in 
 
- Add you new configuration key in 
- Controllers:
- Create the controller file and fill it with your REST API routes
- Import and use your controller in the parent controller
 
- Middlewares:
- Create your validator middleware in server/core/middlewares/validatorsthat will be used by your controllers
- Add your new middleware file server/core/middlewares/validators/index.tsso it's easier to import
- Create the entry in server/core/types/express.d.tsto attach the database model loaded by your middleware to the express response
 
- Create your validator middleware in 
- Validators:
- Create your validators that will be used by your middlewares in server/core/helpers/custom-validators
 
- Create your validators that will be used by your middlewares in 
- Typescript models:
- Create the API models (request parameters or response) in packages/models
- Add your models in index.tsof current directory to facilitate the imports
 
- Create the API models (request parameters or response) in 
- Sequelize model (BDD):
- If you need to create a new table:
- Create the Sequelize model in server/core/models/:- Create the @Column
- Add some indexes if you need
- Create static methods to load a specific from the database loadBy...
- Create static methods to load a list of models from the database listBy...
- Create the instance method toFormattedJSONthat creates the JSON to send to the REST API from the model
 
- Create the 
- Add your new Sequelize model to server/core/initializers/database.ts
- Create a new file in server/core/typesto define multiple versions of your Sequelize model depending on database associations
- Add this new file to server/core/types/*/index.tsto facilitate the imports
- Create database migrations:
- Create the migration file in server/core/initializers/migrationsusing raw SQL (copy the same SQL query as at PeerTube startup)
- Update LAST_MIGRATION_VERSIONinserver/core/initializers/constants.ts
 
- Create the migration file in 
 
- Create the Sequelize model in 
- If updating database schema (adding/removing/renaming a column):
- Update the sequelize models in server/core/models/
- Add migrations:
- Create the migration file in initializers/migrationsusing Sequelize Query Interface (.addColumn,.dropTable,.changeColumn)
- Update LAST_MIGRATION_VERSIONinserver/core/initializers/constants.ts
 
- Create the migration file in 
 
- Update the sequelize models in 
 
- If you need to create a new table:
- Notifications:
- Create the new notification model in packages/models/src/users/user-notification.model.ts
- Create the notification logic in server/core/lib/notifier/shared:- Email subject has a common prefix (defined by the admin in PeerTube configuration)
 
- Add your notification to server/core/lib/notifier/notifier.ts
- Create the email template in server/core/lib/emails:- A text version is automatically generated from the HTML
- The template usually extends ../common/grettingsthat already says "Hi" and "Cheers". You just have to write the title and the content blocks that will be inserted in the appropriate places in the HTML template
 
- If you need to associate a new table with userNotification:- Associate the new table in UserNotificationModel(don't forget the index)
- Add the object property in the API model definition (packages/models/src/users/user-notification.model.ts)
- Add the object in UserNotificationModel.toFormattedJSON
- Handle this new notification type in client (UserNotificationsComponent)
- Handle the new object property in client model (UserNotification)
 
- Associate the new table in 
 
- Create the new notification model in 
- Tests:
- Create your command class in packages/server-commands/that will wrap HTTP requests to your new endpoint
- Add your command file in index.tsof current directory
- Instantiate your command class in packages/server-commands/src/server/core.ts
- Create your test file in server/core/tests/api/check-paramsto test middleware validators/authentification/user rights (offensive tests)
- Add it to server/core/tests/api/check-params/index.ts
- Create your test file in server/core/tests/apito test your new endpoints
- Add it to index.tsof current directory
- Add your notification test in server/core/tests/api/notifications
 
- Create your command class in 
- Update REST API documentation in support/doc/api/openapi.yaml