Skip to content

Commit

Permalink
feat: experimental author info (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
vnugent committed Mar 13, 2023
1 parent 81243e0 commit 300a28b
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/db/ClimbTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ export interface ClimbChangeInputType {
protection?: string
fa?: string
length?: number
experimentalAuthor?: {
displayName: string
url: string
}
}

type UpdatableClimbFieldsType = Pick<ClimbType, 'fa' | 'name' | 'type' | 'gradeContext' | 'grades' | 'content' | 'length'>
Expand Down
23 changes: 23 additions & 0 deletions src/db/UserSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import mongoose from 'mongoose'
import muuid from 'uuid-mongodb'

import { ExperimentalUserType } from './UserTypes.js'

const { Schema } = mongoose

export const ExperimentalUserSchema = new Schema<ExperimentalUserType>({
_id: {
type: 'object',
value: { type: 'Buffer' },
default: () => muuid.v4()
},
displayName: { type: Schema.Types.String, required: true, index: true },
url: { type: Schema.Types.String, required: true, index: true }
}, {
_id: false,
timestamps: true
})

export const getExperimentalUserModel = (): mongoose.Model<ExperimentalUserType> => {
return mongoose.model('exp_users', ExperimentalUserSchema)
}
10 changes: 10 additions & 0 deletions src/db/UserTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { MUUID } from 'uuid-mongodb'

export interface ExperimentalUserType {
_id: MUUID
displayName: string
nickname: string
url: string
createdAt: Date
updatedAt: Date
}
12 changes: 11 additions & 1 deletion src/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getTickModel } from './TickSchema.js'
import { getXMediaModel } from './XMediaSchema.js'
import { getPostModel } from './PostSchema.js'
import { getChangeLogModel } from './ChangeLogSchema.js'
import { getExperimentalUserModel } from './UserSchema.js'
import { logger } from '../logger.js'
import streamListener from './edit/streamListener.js'

Expand Down Expand Up @@ -85,4 +86,13 @@ export const defaultPostConnect = async (): Promise<void> => {
// eslint-disable-next-line
process.on('SIGINT', gracefulExit).on('SIGTERM', gracefulExit)

export { getMediaModel, getAreaModel, getTickModel, getClimbModel, getChangeLogModel, getXMediaModel, getPostModel }
export {
getMediaModel,
getAreaModel,
getTickModel,
getClimbModel,
getChangeLogModel,
getXMediaModel,
getPostModel,
getExperimentalUserModel
}
6 changes: 6 additions & 0 deletions src/graphql/schema/ClimbEdit.gql
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ input SingleClimbChangeInput {
fa: String
"Length in meters"
length: Int
experimentalAuthor: ExperimentalAuthorType
}

input DisciplineType {
Expand All @@ -63,3 +64,8 @@ input DisciplineType {
"https://en.wikipedia.org/wiki/Top_rope_climbing"
tr: Boolean
}

input ExperimentalAuthorType {
displayName: String!
url: String!
}
53 changes: 53 additions & 0 deletions src/model/ExperimentalUserDataSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { MongoDataSource } from 'apollo-datasource-mongodb'
import mongoose, { ClientSession } from 'mongoose'
import muuid, { MUUID } from 'uuid-mongodb'
import { v5 as uuidv5, NIL } from 'uuid'

import { getExperimentalUserModel } from '../db/index.js'
import { ExperimentalUserType } from '../db/UserTypes.js'

export default class MediaDataSource extends MongoDataSource<ExperimentalUserType> {
experimentUserModel = getExperimentalUserModel()

/**
* Create or update a user.
* @param session transaction
* @param inputDisplayName
* @param inputUrl
* @returns User UUID if successful. null otherwise.
*/
async updateUser (session: ClientSession, inputDisplayName: string, inputUrl: string): Promise<MUUID|null> {
const url: string = inputUrl
let displayName = inputDisplayName != null ? inputDisplayName.trim().substring(0, 50) : ''
let uuid: MUUID
if (url == null || url.trim() === '') {
if (displayName === '') {
// displayName and url are both null/empty
return null
}
uuid = muuid.v4()
} else {
// generate uuid from inputUrl
uuid = muuid.from(uuidv5(inputUrl, NIL))
if (displayName === '') {
displayName = `u_${uuid.toUUID().toString()}`
}
}

const filter = {
_id: uuid
}
const doc = {
displayName,
url
}
const rs = await this.experimentUserModel.findOneAndUpdate(filter, doc, { new: true, upsert: true, session }).lean()

if (rs._id != null) {
return rs._id
}
return null
}
}

export const createInstance = (): MediaDataSource => new MediaDataSource(mongoose.connection.db.collection(getExperimentalUserModel().modelName))
16 changes: 14 additions & 2 deletions src/model/MutableClimbDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { ClientSession } from 'mongoose'

import { ClimbChangeDocType, ClimbChangeInputType, ClimbEditOperationType } from '../db/ClimbTypes.js'
import ClimbDataSource from './ClimbDataSource.js'
import { createInstance as createExperimentalUserDataSource } from './ExperimentalUserDataSource.js'
import { sanitizeDisciplines, gradeContextToGradeScales, createGradeObject } from '../GradeUtils.js'
import { getClimbModel } from '../db/ClimbSchema.js'
import { ChangeRecordMetadataType } from '../db/ChangeLogType.js'
import { changelogDataSource } from './ChangeLogDataSource.js'
import { sanitize, sanitizeStrict } from '../utils/sanitize.js'

export default class MutableClimbDataSource extends ClimbDataSource {
experimentalUserDataSource = createExperimentalUserDataSource()

async _addOrUpdateClimbs (userId: MUUID, session: ClientSession, parentId: MUUID, userInput: ClimbChangeInputType[]): Promise<string[]> {
const newClimbIds = new Array<MUUID>(userInput.length)
for (let i = 0; i < newClimbIds.length; i++) {
Expand Down Expand Up @@ -107,6 +110,15 @@ export default class MutableClimbDataSource extends ClimbDataSource {
throw new UserInputError(`Can't add new climbs without name. (Index[index=${i}])`)
}

// See https://github.com/OpenBeta/openbeta-graphql/issues/244
const author = userInput[i].experimentalAuthor
let experimentalUserId: MUUID | null = null
if (author != null) {
experimentalUserId = await this.experimentalUserDataSource.updateUser(session, author.displayName, author.url)
}

console.log('#xperimental uiser', experimentalUserId)

const typeSafeDisciplines = sanitizeDisciplines(userInput[i]?.disciplines)

const grade = userInput[i].grade
Expand Down Expand Up @@ -139,10 +151,10 @@ export default class MutableClimbDataSource extends ClimbDataSource {
lnglat: parent.metadata.lnglat,
...userInput[i]?.leftRightIndex != null && { left_right_index: userInput[i].leftRightIndex }
},
...!idList[i].existed && { createdBy: userId },
...!idList[i].existed && { createdBy: experimentalUserId ?? userId },
...idList[i].existed && { updatedBy: userId },
_change: {
user: userId,
user: experimentalUserId ?? userId,
historyId: change._id,
prevHistoryId: undefined,
operation: opType,
Expand Down

0 comments on commit 300a28b

Please sign in to comment.