|
|
|
@@ -1018,6 +1018,7 @@ type CallsPersistenceInterface interface {
|
|
|
|
|
Create(tenantID types.TenantID, record *types.CallRecord) error
|
|
|
|
|
Accept(tenantID types.TenantID, callID string, seq int, acceptedAt time.Time) error
|
|
|
|
|
Finish(tenantID types.TenantID, callID string, seq int, status string, durationMS int64, finishedAt time.Time) error
|
|
|
|
|
List(tenantID types.TenantID, uid types.Uid, topic, cursor string, limit int) ([]types.CallRecord, string, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type callsMapper struct{}
|
|
|
|
@@ -1064,6 +1065,521 @@ func (callsMapper) Finish(tenantID types.TenantID, callID string, seq int, statu
|
|
|
|
|
return tenantAdp.TenantCallFinish(tenantID, callID, seq, status, durationMS, finishedAt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (callsMapper) List(tenantID types.TenantID, uid types.Uid, topic, cursor string, limit int) ([]types.CallRecord, string, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantCallList(tenantID, uid, strings.TrimSpace(topic), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type WorkbenchPersistenceInterface interface {
|
|
|
|
|
Get(tenantID types.TenantID, uid types.Uid) ([]types.WorkbenchModule, int, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type workbenchMapper struct{}
|
|
|
|
|
|
|
|
|
|
var Workbench WorkbenchPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (workbenchMapper) Get(tenantID types.TenantID, uid types.Uid) ([]types.WorkbenchModule, int, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, 0, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, 0, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantWorkbenchModules(tenantID, uid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type OrganizationPersistenceInterface interface {
|
|
|
|
|
ListDepartments(tenantID types.TenantID, uid types.Uid, parentID, cursor string, limit int) ([]types.OrganizationDepartment, string, error)
|
|
|
|
|
ListMembers(tenantID types.TenantID, uid types.Uid, departmentID, cursor string, limit int) ([]types.OrganizationMember, string, error)
|
|
|
|
|
Search(tenantID types.TenantID, uid types.Uid, queryText, resultTypes, cursor string, limit int) ([]types.OrganizationSearchItem, string, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type organizationMapper struct{}
|
|
|
|
|
|
|
|
|
|
var Organization OrganizationPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (organizationMapper) ListDepartments(tenantID types.TenantID, uid types.Uid, parentID, cursor string, limit int) ([]types.OrganizationDepartment, string, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantOrganizationDepartments(tenantID, uid, strings.TrimSpace(parentID), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (organizationMapper) ListMembers(tenantID types.TenantID, uid types.Uid, departmentID, cursor string, limit int) ([]types.OrganizationMember, string, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(departmentID) == "" {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantOrganizationMembers(tenantID, uid, strings.TrimSpace(departmentID), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (organizationMapper) Search(tenantID types.TenantID, uid types.Uid, queryText, resultTypes, cursor string, limit int) ([]types.OrganizationSearchItem, string, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(queryText) == "" {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantOrganizationSearch(tenantID, uid, strings.TrimSpace(queryText), strings.TrimSpace(resultTypes), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MeetingsPersistenceInterface interface {
|
|
|
|
|
Create(tenantID types.TenantID, uid types.Uid, meeting *types.Meeting, attendeeIDs []types.Uid) (*types.Meeting, error)
|
|
|
|
|
Get(tenantID types.TenantID, uid types.Uid, meetingID string) (*types.Meeting, error)
|
|
|
|
|
Update(tenantID types.TenantID, uid types.Uid, meetingID string, patch types.MeetingPatch, idempotencyKey string) (*types.Meeting, error)
|
|
|
|
|
Cancel(tenantID types.TenantID, uid types.Uid, meetingID, idempotencyKey string) (*types.Meeting, error)
|
|
|
|
|
Remind(tenantID types.TenantID, uid types.Uid, meetingID, idempotencyKey string) ([]types.MeetingParticipant, error)
|
|
|
|
|
Respond(tenantID types.TenantID, uid types.Uid, meetingID, response string, version int) (*types.Meeting, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type meetingsMapper struct{}
|
|
|
|
|
|
|
|
|
|
var Meetings MeetingsPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Create(tenantID types.TenantID, uid types.Uid, meeting *types.Meeting, attendeeIDs []types.Uid) (*types.Meeting, error) {
|
|
|
|
|
if uid.IsZero() || meeting == nil || !validMeetingForCreate(meeting) {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingCreate(tenantID, uid, meeting, attendeeIDs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Get(tenantID types.TenantID, uid types.Uid, meetingID string) (*types.Meeting, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(meetingID) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingGet(tenantID, uid, strings.TrimSpace(meetingID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Update(tenantID types.TenantID, uid types.Uid, meetingID string, patch types.MeetingPatch, idempotencyKey string) (*types.Meeting, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(meetingID) == "" || patch.Version <= 0 || !validMeetingPatch(patch) {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingUpdate(tenantID, uid, strings.TrimSpace(meetingID), patch, strings.TrimSpace(idempotencyKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Cancel(tenantID types.TenantID, uid types.Uid, meetingID, idempotencyKey string) (*types.Meeting, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(meetingID) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingCancel(tenantID, uid, strings.TrimSpace(meetingID), strings.TrimSpace(idempotencyKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Remind(tenantID types.TenantID, uid types.Uid, meetingID, idempotencyKey string) ([]types.MeetingParticipant, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(meetingID) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingRemind(tenantID, uid, strings.TrimSpace(meetingID), strings.TrimSpace(idempotencyKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meetingsMapper) Respond(tenantID types.TenantID, uid types.Uid, meetingID, response string, version int) (*types.Meeting, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(meetingID) == "" || !validMeetingResponse(response) || version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMeetingRespond(tenantID, uid, strings.TrimSpace(meetingID), strings.TrimSpace(response), version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validMeetingForCreate(meeting *types.Meeting) bool {
|
|
|
|
|
return strings.TrimSpace(meeting.MeetingID) != "" &&
|
|
|
|
|
strings.TrimSpace(meeting.Title) != "" &&
|
|
|
|
|
!meeting.StartAt.IsZero() &&
|
|
|
|
|
!meeting.EndAt.IsZero() &&
|
|
|
|
|
meeting.EndAt.After(meeting.StartAt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validMeetingPatch(patch types.MeetingPatch) bool {
|
|
|
|
|
if patch.Title == nil && patch.StartAt == nil && patch.EndAt == nil && patch.Location == nil && patch.ReminderMinutes == nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if patch.Title != nil && strings.TrimSpace(*patch.Title) == "" {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if patch.StartAt != nil && patch.EndAt != nil && !patch.EndAt.After(*patch.StartAt) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validMeetingResponse(response string) bool {
|
|
|
|
|
switch strings.TrimSpace(response) {
|
|
|
|
|
case types.MeetingResponseAccepted, types.MeetingResponseDeclined, types.MeetingResponseTentative:
|
|
|
|
|
return true
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type DailyReportsPersistenceInterface interface {
|
|
|
|
|
List(tenantID types.TenantID, uid types.Uid, scope, from, to, status, cursor string, limit int) ([]types.DailyReport, string, error)
|
|
|
|
|
CreateDraft(tenantID types.TenantID, uid types.Uid, reportID string, reportDate time.Time) (*types.DailyReport, error)
|
|
|
|
|
Get(tenantID types.TenantID, uid types.Uid, reportID string) (*types.DailyReport, error)
|
|
|
|
|
SaveDraft(tenantID types.TenantID, uid types.Uid, reportID, content string, attachments []string, version int) (*types.DailyReport, error)
|
|
|
|
|
Submit(tenantID types.TenantID, uid types.Uid, reportID string, version int) (*types.DailyReport, error)
|
|
|
|
|
Stats(tenantID types.TenantID, uid types.Uid, date time.Time, departmentID string) (*types.DailyReportStats, error)
|
|
|
|
|
Remind(tenantID types.TenantID, uid types.Uid, date time.Time, userIDs []types.Uid, idempotencyKey string) ([]types.Uid, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type dailyReportsMapper struct{}
|
|
|
|
|
|
|
|
|
|
var DailyReports DailyReportsPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) List(tenantID types.TenantID, uid types.Uid, scope, from, to, status, cursor string, limit int) ([]types.DailyReport, string, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportList(tenantID, uid, strings.TrimSpace(scope), strings.TrimSpace(from), strings.TrimSpace(to), strings.TrimSpace(status), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) CreateDraft(tenantID types.TenantID, uid types.Uid, reportID string, reportDate time.Time) (*types.DailyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || reportDate.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportCreateDraft(tenantID, uid, strings.TrimSpace(reportID), reportDate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) Get(tenantID types.TenantID, uid types.Uid, reportID string) (*types.DailyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportGet(tenantID, uid, strings.TrimSpace(reportID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) SaveDraft(tenantID types.TenantID, uid types.Uid, reportID, content string, attachments []string, version int) (*types.DailyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportSaveDraft(tenantID, uid, strings.TrimSpace(reportID), content, attachments, version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) Submit(tenantID types.TenantID, uid types.Uid, reportID string, version int) (*types.DailyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportSubmit(tenantID, uid, strings.TrimSpace(reportID), version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) Stats(tenantID types.TenantID, uid types.Uid, date time.Time, departmentID string) (*types.DailyReportStats, error) {
|
|
|
|
|
if uid.IsZero() || date.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportStats(tenantID, uid, date, strings.TrimSpace(departmentID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (dailyReportsMapper) Remind(tenantID types.TenantID, uid types.Uid, date time.Time, userIDs []types.Uid, idempotencyKey string) ([]types.Uid, error) {
|
|
|
|
|
if uid.IsZero() || date.IsZero() || strings.TrimSpace(idempotencyKey) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDailyReportRemind(tenantID, uid, date, userIDs, strings.TrimSpace(idempotencyKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MonthlyReportsPersistenceInterface interface {
|
|
|
|
|
List(tenantID types.TenantID, uid types.Uid, scope, fromMonth, toMonth, status, cursor string, limit int) ([]types.MonthlyReport, string, error)
|
|
|
|
|
CreateDraft(tenantID types.TenantID, uid types.Uid, reportID, month string) (*types.MonthlyReport, error)
|
|
|
|
|
Get(tenantID types.TenantID, uid types.Uid, reportID string) (*types.MonthlyReport, error)
|
|
|
|
|
SaveDraft(tenantID types.TenantID, uid types.Uid, reportID, workSummary, nextPlan string, attachments []string, version int) (*types.MonthlyReport, error)
|
|
|
|
|
Submit(tenantID types.TenantID, uid types.Uid, reportID string, version int) (*types.MonthlyReport, error)
|
|
|
|
|
Stats(tenantID types.TenantID, uid types.Uid, month, departmentID string) (*types.MonthlyReportStats, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type monthlyReportsMapper struct{}
|
|
|
|
|
|
|
|
|
|
var MonthlyReports MonthlyReportsPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) List(tenantID types.TenantID, uid types.Uid, scope, fromMonth, toMonth, status, cursor string, limit int) ([]types.MonthlyReport, string, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, "", types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
if limit <= 0 || limit > 100 {
|
|
|
|
|
limit = 50
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, "", err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportList(tenantID, uid, strings.TrimSpace(scope), strings.TrimSpace(fromMonth), strings.TrimSpace(toMonth), strings.TrimSpace(status), strings.TrimSpace(cursor), limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) CreateDraft(tenantID types.TenantID, uid types.Uid, reportID, month string) (*types.MonthlyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || strings.TrimSpace(month) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportCreateDraft(tenantID, uid, strings.TrimSpace(reportID), strings.TrimSpace(month))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) Get(tenantID types.TenantID, uid types.Uid, reportID string) (*types.MonthlyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportGet(tenantID, uid, strings.TrimSpace(reportID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) SaveDraft(tenantID types.TenantID, uid types.Uid, reportID, workSummary, nextPlan string, attachments []string, version int) (*types.MonthlyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportSaveDraft(tenantID, uid, strings.TrimSpace(reportID), workSummary, nextPlan, attachments, version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) Submit(tenantID types.TenantID, uid types.Uid, reportID string, version int) (*types.MonthlyReport, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(reportID) == "" || version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportSubmit(tenantID, uid, strings.TrimSpace(reportID), version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (monthlyReportsMapper) Stats(tenantID types.TenantID, uid types.Uid, month, departmentID string) (*types.MonthlyReportStats, error) {
|
|
|
|
|
if uid.IsZero() || strings.TrimSpace(month) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMonthlyReportStats(tenantID, uid, strings.TrimSpace(month), strings.TrimSpace(departmentID))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type MailboxPersistenceInterface interface {
|
|
|
|
|
Config(tenantID types.TenantID, uid types.Uid) (*types.MailboxConfig, error)
|
|
|
|
|
Submit(tenantID types.TenantID, uid types.Uid, submission *types.MailboxSubmission, idempotencyKey string) (*types.MailboxSubmission, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type mailboxMapper struct{}
|
|
|
|
|
|
|
|
|
|
var Mailbox MailboxPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (mailboxMapper) Config(tenantID types.TenantID, uid types.Uid) (*types.MailboxConfig, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMailboxConfigGet(tenantID, uid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (mailboxMapper) Submit(tenantID types.TenantID, uid types.Uid, submission *types.MailboxSubmission, idempotencyKey string) (*types.MailboxSubmission, error) {
|
|
|
|
|
if uid.IsZero() || submission == nil || strings.TrimSpace(submission.SubmissionID) == "" ||
|
|
|
|
|
strings.TrimSpace(submission.Subject) == "" || strings.TrimSpace(submission.Content) == "" ||
|
|
|
|
|
strings.TrimSpace(idempotencyKey) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantMailboxSubmissionCreate(tenantID, uid, submission, strings.TrimSpace(idempotencyKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ProfilePersistenceInterface interface {
|
|
|
|
|
Get(tenantID types.TenantID, uid types.Uid) (*types.UserProfile, error)
|
|
|
|
|
Update(tenantID types.TenantID, uid types.Uid, patch types.UserProfilePatch) (*types.UserProfile, error)
|
|
|
|
|
GetPrivacy(tenantID types.TenantID, uid types.Uid) (*types.UserPrivacySettings, error)
|
|
|
|
|
UpdatePrivacy(tenantID types.TenantID, uid types.Uid, patch types.UserPrivacyPatch) (*types.UserPrivacySettings, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type profileMapper struct{}
|
|
|
|
|
|
|
|
|
|
var Profiles ProfilePersistenceInterface
|
|
|
|
|
|
|
|
|
|
type AppReleasePersistenceInterface interface {
|
|
|
|
|
Latest(tenantID types.TenantID, platform, channel string) (*types.AppRelease, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type appReleaseMapper struct{}
|
|
|
|
|
|
|
|
|
|
var AppReleases AppReleasePersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (appReleaseMapper) Latest(tenantID types.TenantID, platform, channel string) (*types.AppRelease, error) {
|
|
|
|
|
platform = strings.ToLower(strings.TrimSpace(platform))
|
|
|
|
|
channel = strings.ToLower(strings.TrimSpace(channel))
|
|
|
|
|
if platform == "" || channel == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantAppReleaseLatest(tenantID, platform, channel)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type DevicePushTokenPersistenceInterface interface {
|
|
|
|
|
Upsert(tenantID types.TenantID, token *types.DevicePushToken) (*types.DevicePushToken, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type devicePushTokenMapper struct{}
|
|
|
|
|
|
|
|
|
|
var DevicePushTokens DevicePushTokenPersistenceInterface
|
|
|
|
|
|
|
|
|
|
func (devicePushTokenMapper) Upsert(tenantID types.TenantID, token *types.DevicePushToken) (*types.DevicePushToken, error) {
|
|
|
|
|
if token == nil || token.UserID.IsZero() || strings.TrimSpace(token.DeviceID) == "" ||
|
|
|
|
|
strings.TrimSpace(token.Provider) == "" || strings.TrimSpace(token.Token) == "" {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantDevicePushTokenUpsert(tenantID, token)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (profileMapper) Get(tenantID types.TenantID, uid types.Uid) (*types.UserProfile, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantUserProfileGet(tenantID, uid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (profileMapper) Update(tenantID types.TenantID, uid types.Uid, patch types.UserProfilePatch) (*types.UserProfile, error) {
|
|
|
|
|
if uid.IsZero() || patch.Version <= 0 || !validUserProfilePatch(patch) {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantUserProfileUpdate(tenantID, uid, patch)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (profileMapper) GetPrivacy(tenantID types.TenantID, uid types.Uid) (*types.UserPrivacySettings, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantUserPrivacyGet(tenantID, uid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (profileMapper) UpdatePrivacy(tenantID types.TenantID, uid types.Uid, patch types.UserPrivacyPatch) (*types.UserPrivacySettings, error) {
|
|
|
|
|
if uid.IsZero() || patch.Version <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantUserPrivacyUpdate(tenantID, uid, patch)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validUserProfilePatch(patch types.UserProfilePatch) bool {
|
|
|
|
|
if patch.AvatarFileID == nil && patch.Nickname == nil && patch.BirthDate == nil && patch.Signature == nil && patch.Gender == nil && patch.Region == nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if patch.Nickname != nil {
|
|
|
|
|
name := strings.TrimSpace(*patch.Nickname)
|
|
|
|
|
if len([]rune(name)) == 0 || len([]rune(name)) > 32 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if patch.Signature != nil && len([]rune(*patch.Signature)) > 120 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type RelationsPersistenceInterface interface {
|
|
|
|
|
CreateFriendRequest(tenantID types.TenantID, req *types.FriendRequest) (*types.FriendRequest, error)
|
|
|
|
|
ListFriendRequests(tenantID types.TenantID, uid types.Uid, direction, status, cursor string, limit int) ([]types.FriendRequestListItem, string, error)
|
|
|
|
@@ -2015,6 +2531,8 @@ type UserSecurityPersistenceInterface interface {
|
|
|
|
|
GetIndependentPassword(tenantID types.TenantID, uid types.Uid, purpose string) (*types.IndependentPassword, error)
|
|
|
|
|
UpsertIndependentPassword(tenantID types.TenantID, pass *types.IndependentPassword) error
|
|
|
|
|
UpdateIndependentPasswordAttempts(tenantID types.TenantID, uid types.Uid, purpose string, attempts int, lockedUntil *time.Time, updatedAt time.Time) error
|
|
|
|
|
GetYouthMode(tenantID types.TenantID, uid types.Uid) (*types.YouthModeSettings, error)
|
|
|
|
|
SetYouthMode(tenantID types.TenantID, uid types.Uid, enabled bool, policyVersion int, now time.Time) (*types.YouthModeSettings, error)
|
|
|
|
|
CreateSystemNotification(tenantID types.TenantID, notification *types.SystemNotification) error
|
|
|
|
|
ListSystemNotifications(tenantID types.TenantID, uid types.Uid, cursor string, limit int) ([]types.SystemNotification, string, error)
|
|
|
|
|
MarkSystemNotificationRead(tenantID types.TenantID, uid types.Uid, eventID string, readAt time.Time) error
|
|
|
|
@@ -2106,6 +2624,28 @@ func (userSecurityMapper) UpdateIndependentPasswordAttempts(tenantID types.Tenan
|
|
|
|
|
return tenantAdp.TenantIndependentPasswordUpdateAttempts(tenantID, uid, purpose, attempts, lockedUntil, updatedAt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (userSecurityMapper) GetYouthMode(tenantID types.TenantID, uid types.Uid) (*types.YouthModeSettings, error) {
|
|
|
|
|
if uid.IsZero() {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantYouthModeGet(tenantID, uid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (userSecurityMapper) SetYouthMode(tenantID types.TenantID, uid types.Uid, enabled bool, policyVersion int, now time.Time) (*types.YouthModeSettings, error) {
|
|
|
|
|
if uid.IsZero() || policyVersion <= 0 {
|
|
|
|
|
return nil, types.ErrMalformed
|
|
|
|
|
}
|
|
|
|
|
tenantAdp, err := tenantBusinessAdapter(tenantID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return tenantAdp.TenantYouthModeSet(tenantID, uid, enabled, policyVersion, now)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (userSecurityMapper) CreateSystemNotification(tenantID types.TenantID, notification *types.SystemNotification) error {
|
|
|
|
|
if notification == nil || notification.TenantID != tenantID {
|
|
|
|
|
return types.ErrMalformed
|
|
|
|
@@ -2232,6 +2772,15 @@ func init() {
|
|
|
|
|
Subs = subsMapper{}
|
|
|
|
|
Messages = messagesMapper{}
|
|
|
|
|
Calls = callsMapper{}
|
|
|
|
|
Workbench = workbenchMapper{}
|
|
|
|
|
Organization = organizationMapper{}
|
|
|
|
|
Meetings = meetingsMapper{}
|
|
|
|
|
DailyReports = dailyReportsMapper{}
|
|
|
|
|
MonthlyReports = monthlyReportsMapper{}
|
|
|
|
|
Mailbox = mailboxMapper{}
|
|
|
|
|
Profiles = profileMapper{}
|
|
|
|
|
AppReleases = appReleaseMapper{}
|
|
|
|
|
DevicePushTokens = devicePushTokenMapper{}
|
|
|
|
|
Devices = deviceMapper{}
|
|
|
|
|
Files = fileMapper{}
|
|
|
|
|
PCache = pcacheMapper{}
|
|
|
|
|