Improvments
This commit is contained in:
		
							parent
							
								
									fcb7687c05
								
							
						
					
					
						commit
						b637aeefe9
					
				
					 8 changed files with 416 additions and 44 deletions
				
			
		
							
								
								
									
										193
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										193
									
								
								README.md
									
										
									
									
									
								
							|  | @ -1,3 +1,196 @@ | |||
| # GoSkola24API | ||||
| 
 | ||||
| Go module for easy interaction with the Skola24 API. | ||||
| 
 | ||||
| The only data you need to use this module is the hostname of your target institution. | ||||
| Available hostnames can be found in a list [here](https://www.skola24.se/Applications/Authentication/login.aspx). | ||||
| 
 | ||||
| If you know of a way to get these via API, without scraping, please let me know. | ||||
| 
 | ||||
| Please remember that you can only retrieve data within the currently active hostname/domain. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Getting started | ||||
| 
 | ||||
| SomeExampleHere | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Methods | ||||
| 
 | ||||
| Here is a list of all available methods, complete with detailed descriptions. | ||||
| 
 | ||||
| ## GetTerms() (_result, _error) | ||||
| 
 | ||||
| Retrieves all currently available terms (aka semesters). | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| None. | ||||
| 
 | ||||
| ### Returns | ||||
| 
 | ||||
| **_result**: < [Terms](#terms) > Holds the retrieved terms data. | ||||
| 
 | ||||
| **_error**: < error > Holds standard error data if errors were encountered. | ||||
| 
 | ||||
| ## GetSchools() (_result, _error) | ||||
| 
 | ||||
| Retrieves all available schools. | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| None. | ||||
| 
 | ||||
| ### Returns | ||||
| 
 | ||||
| **_result**: < [] [School](#school) > Array of available schools. | ||||
| 
 | ||||
| **_error**: < error > Holds standard error data if errors were encountered. | ||||
| 
 | ||||
| ## GetRooms(school, checkAvailability) (_result, _error) | ||||
| 
 | ||||
| Retrieves all rooms in a school. | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| **school**: < [School](#school) > School to get rooms from. | ||||
| 
 | ||||
| **checkAvailability**: < bool > If stored availability data should be used to skip requests for unavailable data. | ||||
| 
 | ||||
| ### Returns | ||||
| 
 | ||||
| **_result**: < [] [Room](#room) > Array of available rooms. | ||||
| 
 | ||||
| **_error**: < error > Holds standard error data if errors were encountered. | ||||
| 
 | ||||
| ## GetTeachers(school, checkAvailability) (_result, _error) | ||||
| 
 | ||||
| Retrieves all teachers in a school. | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| **school**: < [School](#school) > School to get teachers from. | ||||
| 
 | ||||
| **checkAvailability**: < bool > If stored availability data should be used to skip requests for unavailable data. | ||||
| 
 | ||||
| ### Returns | ||||
| 
 | ||||
| **_result**: < [] [Teacher](#teacher) > Array of available teachers. | ||||
| 
 | ||||
| **_error**: < error > Holds standard error data if errors were encountered. | ||||
| 
 | ||||
| ## GetStudents(school, checkAvailability) (_result, _error) | ||||
| 
 | ||||
| Retrieves all students in a school. | ||||
| 
 | ||||
| WARNING: Use with caution. I am yet to find a host/school that provides this data, and therefor this method is not typed. | ||||
| 
 | ||||
| ### Parameters | ||||
| 
 | ||||
| **school**: < [School](#school) > School to get students from. | ||||
| 
 | ||||
| **checkAvailability**: < bool > If stored availability data should be used to skip requests for unavailable data. | ||||
| 
 | ||||
| ### Returns | ||||
| 
 | ||||
| **_result**: < any > Returned student data. WARNING: Types currently unknown. | ||||
| 
 | ||||
| **_error**: < error > Holds standard error data if errors were encountered. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Types | ||||
| 
 | ||||
| ## Terms | ||||
| 
 | ||||
| Holds terms (aka semesters) data. | ||||
| 
 | ||||
| ### Fields | ||||
| 
 | ||||
| **ActiveTerms**: < [] [SchoolTerm](#schoolterm) > Array of currently active terms. | ||||
| 
 | ||||
| **UseSchoolYearsFeatures**: < bool > Purpose unknown. | ||||
| 
 | ||||
| ## SchoolTerm | ||||
| 
 | ||||
| Represents a school term. | ||||
| 
 | ||||
| ### Fields | ||||
| 
 | ||||
| **Start**: < string > Term startdate. | ||||
| 
 | ||||
| **TermId**: < string > ID of the term (GUID). | ||||
| 
 | ||||
| **Name**: < string > Friendlyname of the term. | ||||
| 
 | ||||
| **End**: < string > Term enddate. | ||||
| 
 | ||||
| ## School | ||||
| 
 | ||||
| Represents a school. | ||||
| 
 | ||||
| ### Fields | ||||
| 
 | ||||
| **Name**: < string > Friendlyname of the school. | ||||
| 
 | ||||
| **SchoolId**: < string > ID of the school (GUID). | ||||
| 
 | ||||
| **HostName**: < string > The hostname / domain the school belongs to. | ||||
| 
 | ||||
| **AllowCalendarExport**: < string > Whether or not school allows traditional calendar export (does not affect exports via this module). | ||||
| 
 | ||||
| **AvailableData**: < [DataAvailability](#dataavailability) > Types of data available for retrieval on the school. | ||||
| 
 | ||||
| ## DataAvailability | ||||
| 
 | ||||
| Defines types of data available on a specific entity. | ||||
| 
 | ||||
| ### Fields | ||||
| 
 | ||||
| **HasClasses**: < bool > If entity provides classes data. | ||||
| 
 | ||||
| **HasCourses**: < bool > If entity provides courses data. | ||||
| 
 | ||||
| **HasGroups**: < bool > If entity provides groups data. | ||||
| 
 | ||||
| **HasResources**: < bool > If entity provides resources data. | ||||
| 
 | ||||
| **HasRooms**: < bool > If entity provides rooms data. | ||||
| 
 | ||||
| **HasStudents**: < bool > If entity provides students data. | ||||
| 
 | ||||
| **HasSubjects**: < bool > If entity provides teachers data. | ||||
| 
 | ||||
| ## Room | ||||
| 
 | ||||
| Represents a room. | ||||
| 
 | ||||
| **Name**: < string > Friendlyname of the room. | ||||
| 
 | ||||
| **RoomId**: < string > ID of the room (GUID). | ||||
| 
 | ||||
| **External**: < bool > Purpose unknown, but assumed to indicate a room physically isolated from the rest of the school. | ||||
| 
 | ||||
| ## Teacher | ||||
| 
 | ||||
| Represents a teacher. | ||||
| 
 | ||||
| **FirstName**: < string > Teacher's first name. | ||||
| 
 | ||||
| **LastName**: < string > Teacher's last name. | ||||
| 
 | ||||
| **FullName**: < string > Full name (usually firstname+lastname+friendlyid). | ||||
| 
 | ||||
| **FriendlyId**: < string > Friendly/readable ID, usually teacher's initials. | ||||
| 
 | ||||
| **TeacherId**: < string > ID of the teacher (GUID). | ||||
| 
 | ||||
| **IsActive**: < bool > Purpose unknown. | ||||
| 
 | ||||
| **Integrity**: < bool > Purpose unknown. | ||||
| 
 | ||||
| **Reported**: < bool > Purpose unknown. | ||||
| 
 | ||||
| **ReadOnly**: < bool > Purpose unknown. | ||||
|  | @ -30,11 +30,25 @@ func main() { | |||
| 		fmt.Println(err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println(rooms) | ||||
| 
 | ||||
| 	for _, room := range rooms { | ||||
| 		fmt.Println(room.Name) | ||||
| 	} | ||||
| 
 | ||||
| 	teachers, err := api.GetTeachers(schools[4], true) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, teacher := range teachers { | ||||
| 		fmt.Println(teacher.FullName) | ||||
| 	} | ||||
| 
 | ||||
| 	students, err := api.GetStudents(schools[4], true) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println(students) | ||||
| 
 | ||||
| 	fmt.Println(key) | ||||
| } | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ package requests | |||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"git.zervo.org/zervo/GoSkola24API/internal/types" | ||||
| 	pubtypes "git.zervo.org/zervo/GoSkola24API/pkg/goskola24api/types" | ||||
|  | @ -53,17 +52,12 @@ func GetRooms(school pubtypes.School, checkAvailability bool) (_result []pubtype | |||
| 		return nil, errors.New("failed to get rooms: " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println(school) | ||||
| 	fmt.Println(responseMap) | ||||
| 
 | ||||
| 	// Extract rooms as []interface{} | ||||
| 	roomsRaw, ok := responseMap["rooms"].([]interface{}) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("missing or invalid \"rooms\" field in response") | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println(roomsRaw) | ||||
| 
 | ||||
| 	// Convert raw rooms into usable room type | ||||
| 	var rooms []pubtypes.Room | ||||
| 	for _, roomRaw := range roomsRaw { | ||||
|  | @ -72,16 +66,11 @@ func GetRooms(school pubtypes.School, checkAvailability bool) (_result []pubtype | |||
| 			return nil, errors.New("unexpected room format") | ||||
| 		} | ||||
| 
 | ||||
| 		// Extract fields from each room | ||||
| 		roomName, _ := roomMap["name"].(string) | ||||
| 		roomId, _ := roomMap["eid"].(string) | ||||
| 		external, _ := roomMap["external"].(bool) | ||||
| 
 | ||||
| 		// Map to struct | ||||
| 		// Create room struct | ||||
| 		room := pubtypes.Room{ | ||||
| 			Name:     roomName, | ||||
| 			RoomId:   roomId, | ||||
| 			External: external, | ||||
| 			Name:     func() string { val, _ := roomMap["name"].(string); return val }(), | ||||
| 			RoomId:   func() string { val, _ := roomMap["eid"].(string); return val }(), | ||||
| 			External: func() bool { val, _ := roomMap["external"].(bool); return val }(), | ||||
| 		} | ||||
| 
 | ||||
| 		rooms = append(rooms, room) | ||||
|  |  | |||
|  | @ -78,39 +78,25 @@ func GetSchools(api_host string) (_result []pubtypes.School, _error error) { | |||
| 			return nil, errors.New("unexpected unit format") | ||||
| 		} | ||||
| 
 | ||||
| 		// Extract fields from each unit | ||||
| 		unitGuid, _ := unitMap["unitGuid"].(string) | ||||
| 		unitId, _ := unitMap["unitId"].(string) | ||||
| 		allowCalendarExport, _ := unitMap["allowCalendarExport"].(bool) | ||||
| 		// Extract data from the anonymous field | ||||
| 		anonMap, _ := unitMap["anonymous"].(map[string]interface{}) | ||||
| 
 | ||||
| 		// Same for anonymous units | ||||
| 		hasClasses, _ := anonMap["classes"].(bool) | ||||
| 		hasCourses, _ := anonMap["courses"].(bool) | ||||
| 		hasGroups, _ := anonMap["groups"].(bool) | ||||
| 		hasResources, _ := anonMap["resources"].(bool) | ||||
| 		hasRooms, _ := anonMap["rooms"].(bool) | ||||
| 		hasStudents, _ := anonMap["students"].(bool) | ||||
| 		hasSubjects, _ := anonMap["subjects"].(bool) | ||||
| 		hasTeachers, _ := anonMap["teachers"].(bool) | ||||
| 
 | ||||
| 		availableData := pubtypes.DataAvailability{ | ||||
| 			HasClasses:   hasClasses, | ||||
| 			HasCourses:   hasCourses, | ||||
| 			HasGroups:    hasGroups, | ||||
| 			HasResources: hasResources, | ||||
| 			HasRooms:     hasRooms, | ||||
| 			HasStudents:  hasStudents, | ||||
| 			HasSubjects:  hasSubjects, | ||||
| 			HasTeachers:  hasTeachers, | ||||
| 			HasClasses:   func() bool { val, _ := anonMap["classes"].(bool); return val }(), | ||||
| 			HasCourses:   func() bool { val, _ := anonMap["courses"].(bool); return val }(), | ||||
| 			HasGroups:    func() bool { val, _ := anonMap["groups"].(bool); return val }(), | ||||
| 			HasResources: func() bool { val, _ := anonMap["resources"].(bool); return val }(), | ||||
| 			HasRooms:     func() bool { val, _ := anonMap["rooms"].(bool); return val }(), | ||||
| 			HasStudents:  func() bool { val, _ := anonMap["students"].(bool); return val }(), | ||||
| 			HasSubjects:  func() bool { val, _ := anonMap["subjects"].(bool); return val }(), | ||||
| 			HasTeachers:  func() bool { val, _ := anonMap["teachers"].(bool); return val }(), | ||||
| 		} | ||||
| 
 | ||||
| 		// Map to the struct | ||||
| 		unit := pubtypes.School{ | ||||
| 			Name:                unitId, | ||||
| 			SchoolId:            unitGuid, | ||||
| 			Name:                func() string { val, _ := unitMap["unitId"].(string); return val }(), | ||||
| 			SchoolId:            func() string { val, _ := unitMap["unitGuid"].(string); return val }(), | ||||
| 			HostName:            hostname, | ||||
| 			AllowCalendarExport: allowCalendarExport, | ||||
| 			AllowCalendarExport: func() bool { val, _ := unitMap["allowCalendarExport"].(bool); return val }(), | ||||
| 			AvailableData:       availableData, | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										59
									
								
								internal/requests/get_students.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								internal/requests/get_students.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| /* | ||||
| GoSkola24API | ||||
| Copyright (C) 2024, Marco Vitchi Thulin | ||||
| 
 | ||||
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||||
| 
 | ||||
| This program is free software: you can redistribute it and/or modify | ||||
| it under the terms of the GNU Affero General Public License version 3 | ||||
| as published by the Free Software Foundation. | ||||
| 
 | ||||
| This program is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| GNU Affero General Public License version 3 for more details. | ||||
| 
 | ||||
| This program incorporates external libraries for certain functionalities. | ||||
| These libraries are covered by their respective licenses, and their usage | ||||
| agreements are as outlined in their respective documentation or source | ||||
| code. | ||||
| 
 | ||||
| You should have received a copy of the GNU Affero General Public License | ||||
| along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| package requests | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 
 | ||||
| 	"git.zervo.org/zervo/GoSkola24API/internal/types" | ||||
| 	pubtypes "git.zervo.org/zervo/GoSkola24API/pkg/goskola24api/types" | ||||
| ) | ||||
| 
 | ||||
| // TODO: Create and implement proper students type once we have data | ||||
| 
 | ||||
| func GetStudents(school pubtypes.School, checkAvailability bool) (_result any, _error error) { | ||||
| 	if checkAvailability && !school.AvailableData.HasStudents { | ||||
| 		return nil, errors.New("availability check failed: school does not provide student data") | ||||
| 	} | ||||
| 
 | ||||
| 	filters := types.RequestFilters{ | ||||
| 		Class:   false, | ||||
| 		Course:  false, | ||||
| 		Group:   false, | ||||
| 		Period:  false, | ||||
| 		Room:    false, | ||||
| 		Student: true, | ||||
| 		Subject: false, | ||||
| 		Teacher: false, | ||||
| 	} | ||||
| 
 | ||||
| 	responseMap, err := GetGenericSelection(school, filters) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.New("failed to get students: " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Just return students as-is since we do not have any data do go from | ||||
| 	return responseMap, nil | ||||
| } | ||||
							
								
								
									
										86
									
								
								internal/requests/get_teachers.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								internal/requests/get_teachers.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| /* | ||||
| GoSkola24API | ||||
| Copyright (C) 2024, Marco Vitchi Thulin | ||||
| 
 | ||||
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||||
| 
 | ||||
| This program is free software: you can redistribute it and/or modify | ||||
| it under the terms of the GNU Affero General Public License version 3 | ||||
| as published by the Free Software Foundation. | ||||
| 
 | ||||
| This program is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| GNU Affero General Public License version 3 for more details. | ||||
| 
 | ||||
| This program incorporates external libraries for certain functionalities. | ||||
| These libraries are covered by their respective licenses, and their usage | ||||
| agreements are as outlined in their respective documentation or source | ||||
| code. | ||||
| 
 | ||||
| You should have received a copy of the GNU Affero General Public License | ||||
| along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| package requests | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 
 | ||||
| 	"git.zervo.org/zervo/GoSkola24API/internal/types" | ||||
| 	pubtypes "git.zervo.org/zervo/GoSkola24API/pkg/goskola24api/types" | ||||
| ) | ||||
| 
 | ||||
| func GetTeachers(school pubtypes.School, checkAvailability bool) (_result []pubtypes.Teacher, _error error) { | ||||
| 	if checkAvailability && !school.AvailableData.HasTeachers { | ||||
| 		return nil, errors.New("availability check failed: school does not provide teacher data") | ||||
| 	} | ||||
| 
 | ||||
| 	filters := types.RequestFilters{ | ||||
| 		Class:   false, | ||||
| 		Course:  false, | ||||
| 		Group:   false, | ||||
| 		Period:  false, | ||||
| 		Room:    false, | ||||
| 		Student: false, | ||||
| 		Subject: false, | ||||
| 		Teacher: true, | ||||
| 	} | ||||
| 
 | ||||
| 	responseMap, err := GetGenericSelection(school, filters) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.New("failed to get teachers: " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Extract teachers as []interface{} | ||||
| 	teachersRaw, ok := responseMap["teachers"].([]interface{}) | ||||
| 	if !ok { | ||||
| 		return nil, errors.New("missing or invalid \"teachers\" field in response") | ||||
| 	} | ||||
| 
 | ||||
| 	// Convert raw teachers into usable teacher type | ||||
| 	var teachers []pubtypes.Teacher | ||||
| 	for _, teacherRaw := range teachersRaw { | ||||
| 		teacherMap, ok := teacherRaw.(map[string]interface{}) | ||||
| 		if !ok { | ||||
| 			return nil, errors.New("unexpected room format") | ||||
| 		} | ||||
| 
 | ||||
| 		// Map to struct | ||||
| 		teacher := pubtypes.Teacher{ | ||||
| 			FirstName:  func() string { val, _ := teacherMap["firstName"].(string); return val }(), | ||||
| 			LastName:   func() string { val, _ := teacherMap["lastName"].(string); return val }(), | ||||
| 			FullName:   func() string { val, _ := teacherMap["fullName"].(string); return val }(), | ||||
| 			FriendlyId: func() string { val, _ := teacherMap["id"].(string); return val }(), | ||||
| 			TeacherId:  func() string { val, _ := teacherMap["personGuid"].(string); return val }(), | ||||
| 			IsActive:   func() bool { val, _ := teacherMap["isActiveUser"].(bool); return val }(), | ||||
| 			Integrity:  func() bool { val, _ := teacherMap["integrity"].(bool); return val }(), | ||||
| 			Reported:   func() bool { val, _ := teacherMap["reported"].(bool); return val }(), | ||||
| 			ReadOnly:   func() bool { val, _ := teacherMap["readOnly"].(bool); return val }(), | ||||
| 		} | ||||
| 
 | ||||
| 		teachers = append(teachers, teacher) | ||||
| 	} | ||||
| 
 | ||||
| 	return teachers, nil | ||||
| } | ||||
|  | @ -44,3 +44,11 @@ func (api Skola24API) GetSchools() (_result []pubtypes.School, _error error) { | |||
| func (api Skola24API) GetRooms(school pubtypes.School, checkAvailability bool) (_result []pubtypes.Room, _error error) { | ||||
| 	return requests.GetRooms(school, checkAvailability) | ||||
| } | ||||
| 
 | ||||
| func (api Skola24API) GetTeachers(school pubtypes.School, checkAvailability bool) (_result []pubtypes.Teacher, _error error) { | ||||
| 	return requests.GetTeachers(school, checkAvailability) | ||||
| } | ||||
| 
 | ||||
| func (api Skola24API) GetStudents(school pubtypes.School, checkAvailability bool) (_result any, _error error) { | ||||
| 	return requests.GetStudents(school, checkAvailability) | ||||
| } | ||||
|  |  | |||
							
								
								
									
										37
									
								
								pkg/goskola24api/types/teachers.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								pkg/goskola24api/types/teachers.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| /* | ||||
| GoSkola24API | ||||
| Copyright (C) 2024, Marco Vitchi Thulin | ||||
| 
 | ||||
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||||
| 
 | ||||
| This program is free software: you can redistribute it and/or modify | ||||
| it under the terms of the GNU Affero General Public License version 3 | ||||
| as published by the Free Software Foundation. | ||||
| 
 | ||||
| This program is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| GNU Affero General Public License version 3 for more details. | ||||
| 
 | ||||
| This program incorporates external libraries for certain functionalities. | ||||
| These libraries are covered by their respective licenses, and their usage | ||||
| agreements are as outlined in their respective documentation or source | ||||
| code. | ||||
| 
 | ||||
| You should have received a copy of the GNU Affero General Public License | ||||
| along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| package types | ||||
| 
 | ||||
| type Teacher struct { | ||||
| 	FirstName  string `json:"firstName"` | ||||
| 	LastName   string `json:"lastName"` | ||||
| 	FullName   string `json:"fullName"` | ||||
| 	FriendlyId string `json:"friendlyId"` | ||||
| 	TeacherId  string `json:"teacherId"` | ||||
| 	IsActive   bool   `json:"isActive"` | ||||
| 	Integrity  bool   `json:"integrity"` | ||||
| 	Reported   bool   `json:"reported"` | ||||
| 	ReadOnly   bool   `json:"readOnly"` | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue