# https://gqlgen.com/reference/scalars/ scalar Time scalar Upload # https://gqlgen.com/reference/directives/ directive @hasMinRole(role: Role!) on FIELD_DEFINITION directive @isPrivate on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @meta( gorm: String, ) on OBJECT | FIELD_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION | ENUM | INPUT_OBJECT | ARGUMENT_DEFINITION enum Role { Admin User } enum DeviceType { iOS Android Chrome Firefox InternetExplorer Edge Safari Unknown } enum AuthType { Local LDAP } # ------------------------------------------------------------ # ---------------------- Authentication ---------------------- # ------------------------------------------------------------ enum AuthResult { Success Failure } type AuthResponse { result: AuthResult! device: Device error: String } # ------------------------------------------------------------ # ----------------------- Type Filters ----------------------- # ------------------------------------------------------------ input TimeFilter { equalTo: Time notEqualTo: Time lessThan: Time lessThanOrEqualTo: Time moreThan: Time moreThanOrEqualTo: Time } input IntFilter { equalTo: Int notEqualTo: Int lessThan: Int lessThanOrEqualTo: Int moreThan: Int moreThanOrEqualTo: Int in: [Int!] notIn: [Int!] } input FloatFilter { equalTo: Float notEqualTo: Float lessThan: Float lessThanOrEqualTo: Float moreThan: Float moreThanOrEqualTo: Float in: [Float!] notIn: [Float!] } input BooleanFilter { equalTo: Boolean notEqualTo: Boolean } input IDFilter { equalTo: ID notEqualTo: ID in: [ID!] notIn: [ID!] } input StringFilter { equalTo: String notEqualTo: String startWith: String notStartWith: String endWith: String notEndWith: String contain: String notContain: String in: [String!] notIn: [String!] startWithStrict: String notStartWithStrict: String endWithStrict: String notEndWithStrict: String containStrict: String notContainStrict: String } input RoleFilter { equalTo: Role notEqualTo: Role in: [Role!] notIn: [Role!] } input DeviceTypeFilter { equalTo: DeviceType notEqualTo: DeviceType in: [DeviceType!] notIn: [DeviceType!] } input AuthTypeFilter { equalTo: AuthType notEqualTo: AuthType in: [AuthType!] notIn: [AuthType!] } # ------------------------------------------------------------ # -------------------- Object Definitions -------------------- # ------------------------------------------------------------ type User { id: ID! @meta(gorm: "primaryKey;not null") createdAt: Time updatedAt: Time email: String! @meta(gorm: "not null;unique") username: String! @meta(gorm: "not null;unique") firstName: String lastName: String role: Role! @meta(gorm: "default:User;not null") authType: AuthType! @meta(gorm: "default:Local;not null") password: String @isPrivate devices: [Device!] @meta(gorm: "foreignKey:UserID") mediaItems: [MediaItem!] @meta(gorm: "foreignKey:UserID") } type Device { id: ID! @meta(gorm: "primaryKey;not null") createdAt: Time updatedAt: Time name: String! @meta(gorm: "not null") type: DeviceType! @meta(gorm: "default:Unknown;not null") userID: ID! @meta(gorm: "not null") refreshKey: String @isPrivate } type MediaItem { id: ID! @meta(gorm: "primaryKey;not null") createdAt: Time updatedAt: Time exifDate: Time latitude: Float longitude: Float isVideo: Boolean! @meta(gorm: "default:false;not null") fileName: String! @meta(gorm: "not null") origName: String! @meta(gorm: "not null") tags: [Tag] @meta(gorm: "many2many:media_tags") albums: [Album] @meta(gorm: "many2many:media_albums") userID: ID! @meta(gorm: "not null") } type Tag { id: ID! @meta(gorm: "primaryKey;not null") createdAt: Time updatedAt: Time name: String! @meta(gorm: "unique;not null") } type Album { id: ID! @meta(gorm: "primaryKey;not null") createdAt: Time updatedAt: Time name: String! @meta(gorm: "unique;not null") # userID: ID! @meta(gorm: "not null") } # ------------------------------------------------------------ # ---------------------- Object Filters ---------------------- # ------------------------------------------------------------ input UserFilter { id: IDFilter createdAt: TimeFilter updatedAt: TimeFilter username: StringFilter firstName: StringFilter lastName: StringFilter role: RoleFilter authType: AuthTypeFilter and: UserFilter or: UserFilter } input MediaItemFilter { id: IDFilter createdAt: TimeFilter updatedAt: TimeFilter exifDate: TimeFilter latitude: FloatFilter longitude: FloatFilter isVideo: BooleanFilter origName: StringFilter tags: TagFilter albums: AlbumFilter and: MediaItemFilter or: MediaItemFilter } input DeviceFilter { id: IDFilter createdAt: TimeFilter updatedAt: TimeFilter name: StringFilter type: DeviceTypeFilter and: MediaItemFilter or: MediaItemFilter } input TagFilter { id: IDFilter createdAt: TimeFilter updatedAt: TimeFilter name: StringFilter and: MediaItemFilter or: MediaItemFilter } input AlbumFilter { id: IDFilter createdAt: TimeFilter updatedAt: TimeFilter name: StringFilter and: MediaItemFilter or: MediaItemFilter } # ------------------------------------------------------------ # -------------------------- Inputs -------------------------- # ------------------------------------------------------------ input NewUser { email: String! username: String! firstName: String lastName: String role: Role! authType: AuthType! password: String } input NewMediaItem { file: Upload! tags: [ID!] albums: [ID!] } input NewTag { name: String! } input NewAlbum { name: String! } # ------------------------------------------------------------ # ------------------------ Responses ------------------------- # ------------------------------------------------------------ type PageInfo { count: Int! page: Int! total: Int! } type MediaItemResponse { data: [MediaItem] pageInfo: PageInfo! } type UserResponse { data: [User] pageInfo: PageInfo! } type DeviceResponse { data: [Device] pageInfo: PageInfo! } type TagResponse { data: [Tag] pageInfo: PageInfo! } type AlbumResponse { data: [Album] pageInfo: PageInfo! } # ------------------------------------------------------------ # --------------------- Query & Mutations -------------------- # ------------------------------------------------------------ type Query { # Authentication login( user: String! password: String! deviceID: ID ): AuthResponse! logout: AuthResponse! @hasMinRole(role: User) # Single Item mediaItem( id: ID! delete: Boolean ): MediaItem! @hasMinRole(role: User) device( id: ID! delete: Boolean ): Device! @hasMinRole(role: User) album( id: ID! delete: Boolean ): Album! @hasMinRole(role: User) user( id: ID! delete: Boolean ): User! @hasMinRole(role: Admin) # TODO: Delete All User Content tag( id: ID! delete: Boolean ): Tag! @hasMinRole(role: User) me(delete: Boolean): User! @hasMinRole(role: User) # All mediaItems( delete: Boolean filter: MediaItemFilter count: Int page: Int ): MediaItemResponse! @hasMinRole(role: User) devices( delete: Boolean filter: DeviceFilter count: Int page: Int ): DeviceResponse! @hasMinRole(role: User) albums( delete: Boolean filter: AlbumFilter count: Int page: Int ): AlbumResponse! @hasMinRole(role: User) tags( delete: Boolean filter: TagFilter count: Int page: Int ): TagResponse! @hasMinRole(role: User) users( delete: Boolean filter: UserFilter count: Int page: Int ): UserResponse! @hasMinRole(role: Admin) # TODO: Delete All User Content } type Mutation { createMediaItem(input: NewMediaItem!): MediaItem! @hasMinRole(role: User) createAlbum(input: NewAlbum!): Album! @hasMinRole(role: User) createTag(input: NewTag!): Tag! @hasMinRole(role: User) createUser(input: NewUser!): User! @hasMinRole(role: Admin) }