School service - MathparLearningTeam/Documentation GitHub Wiki

General information

School service is responsible for persisting school profiles, their hierarchy (role hierarchy, classes, groups) and student's studying progress.

Database

There are 5 main entities in the service:

  • School. This is the main entity in the school service. It stores all the required school information. School address is stored in a separate entity called SchoolAddress because it can contain multiple parts. School entity doesn't store the director relation to avoid circular dependency between UserProfile and School entities.
  • SchoolClass. This entity stores all the students in the school class. It is required for utility purposes - when creating a group it is possible to add all students from specific class.
  • SchoolGroup. This entity stores all the students in logical group. Groups can be assigned to learning plans. Single student can be assigned to multiple groups.
  • StudentDiary. This entity stores all the students progresses in studying. It stores the profile id, task id and plan id as PK and a result string which represents validity of user's responses to all the assignments in the task.
  • UserProfile. This entity represents the account's record in the school database. It stores the account's role in the school (referenced using FK). It can also store additional account-related details in scope of school service.

In order to manage all entities we are using JPA (spring-data implementation). DDL are defined explicitly and manageable via sql scripts stored in "resources/ddl/*.sql". If any alteration to DB is required, the new script with the current timestamp should be created to store all the SQL code to make the change. The "dummy_schema.sql" exists to provide some examples of complex SQL queries as well as to be a placeholder if there will be no SQL scripts for some reason (without a single DDL script spring boot will start throwing errors on the startup).

Services

Alongside the default services for CRUD entities operations we have:

  • MathparCalculatorService. This service is responsible for communication with "MathparCalculator" - the cloud computation solution we are using. There are also additional methods in the services for entities (like "isEmailAvailable", "isTokenValid" etc), they are grouped logically - all the methods in regards to account stored in the account service, methods in regards to school in school service etc.

Controllers

There are 2 levels of controllers in the project - public and private. All the public endpoints are beginning with "/api" prefix to indicate that they are accessible from client. All the private endpoints mustn't have this prefix to be accessible only within the private network (within mathpar services). Currently all the public endpoints are located in the "api" package, all the private endpoints are stored without unique package (on the same level as "api" package).

Examples of a public controllers are:

  • ClassController
  • GroupController
  • ProfileController
  • SchoolController Those are endpoints which client is using to work with the service.

Examples of a private controllers are:

  • PrivateSchoolController
  • HealthController Those endpoints are responsible for health monitoring of an application as well as utility methods for other services to use which shouldn't be accessible for client ("getSchoolId" endpoint which returns the id of school associated with profile id).

Properties

In order to function properly service requires additional properties to be supplied, like DB url/username/password, account service url etc. Those properties are injected in runtime using the bean "MathparProperties" defined in "PropertiesConfiguration" class. During the bean creation, it calls the secrets manager service to retrieve properties from a specific namespace and maps it to its own fields. This bean isn't created during the unit test runs to avoid depending on external services and make the testing fully autonomous.

Authentication and authorization

Authentication

School service uses AccountService as CAS (central authentication service) to authenticate users. Authentication is using the OAuth token mechanism. Every time user sends a request it is supplied with the token in headers. Before processing the request, school service uses the SpringSecurity filter chain to extract the token, check its validity and propagate it to other steps.

Authorization

School service is responsible for its own authorization system. In order to do that it requires "PROFILE-ID" header to be passed for any secured endpoint. After authentication (if token is valid) it parses the profile id associated with the request, fetches roles of the profile from database and propagates it to SpringSecurity token object for further validation. Once done, the spring security handles the rest, we just need to indicate required role for the endpoint by using SpringSecurity annotations.