385 lines
8.5 KiB
GraphQL
385 lines
8.5 KiB
GraphQL
|
|
||
|
# 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
|
||
|
}
|
||
|
|
||
|
enum OrderDirection {
|
||
|
ASC
|
||
|
DESC
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# ---------------------- 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
|
||
|
greaterThan: Time
|
||
|
greaterThanOrEqualTo: Time
|
||
|
}
|
||
|
|
||
|
input IntFilter {
|
||
|
equalTo: Int
|
||
|
notEqualTo: Int
|
||
|
lessThan: Int
|
||
|
lessThanOrEqualTo: Int
|
||
|
greaterThan: Int
|
||
|
greaterThanOrEqualTo: Int
|
||
|
}
|
||
|
|
||
|
input FloatFilter {
|
||
|
equalTo: Float
|
||
|
notEqualTo: Float
|
||
|
lessThan: Float
|
||
|
lessThanOrEqualTo: Float
|
||
|
greaterThan: Float
|
||
|
greaterThanOrEqualTo: Float
|
||
|
}
|
||
|
|
||
|
input BooleanFilter {
|
||
|
equalTo: Boolean
|
||
|
notEqualTo: Boolean
|
||
|
}
|
||
|
|
||
|
input IDFilter {
|
||
|
equalTo: ID
|
||
|
notEqualTo: ID
|
||
|
}
|
||
|
|
||
|
input StringFilter {
|
||
|
equalTo: String
|
||
|
notEqualTo: String
|
||
|
startsWith: String
|
||
|
notStartsWith: String
|
||
|
endsWith: String
|
||
|
notEndsWith: String
|
||
|
contains: String
|
||
|
notContains: String
|
||
|
}
|
||
|
|
||
|
input RoleFilter {
|
||
|
equalTo: Role
|
||
|
notEqualTo: Role
|
||
|
}
|
||
|
|
||
|
input DeviceTypeFilter {
|
||
|
equalTo: DeviceType
|
||
|
notEqualTo: DeviceType
|
||
|
}
|
||
|
|
||
|
input AuthTypeFilter {
|
||
|
equalTo: AuthType
|
||
|
notEqualTo: 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")
|
||
|
refreshKey: String @isPrivate
|
||
|
userID: ID! @meta(gorm: "not null")
|
||
|
}
|
||
|
|
||
|
type MediaItem {
|
||
|
id: ID! @meta(gorm: "primaryKey;not null")
|
||
|
createdAt: Time
|
||
|
updatedAt: Time
|
||
|
exifDate: Time
|
||
|
latitude: Float @meta(gorm: "precision:5")
|
||
|
longitude: Float @meta(gorm: "precision:5")
|
||
|
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;foreignKey:ID,UserID;References:ID")
|
||
|
albums: [Album] @meta(gorm: "many2many:media_albums;foreignKey:ID,UserID;Refrences:ID")
|
||
|
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")
|
||
|
userID: ID! @meta(gorm: "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!
|
||
|
}
|
||
|
|
||
|
input Page {
|
||
|
size: Int
|
||
|
page: Int
|
||
|
}
|
||
|
|
||
|
input Order {
|
||
|
by: String
|
||
|
direction: OrderDirection
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# ------------------------ Responses -------------------------
|
||
|
# ------------------------------------------------------------
|
||
|
|
||
|
type PageResponse {
|
||
|
size: Int!
|
||
|
page: Int!
|
||
|
total: Int!
|
||
|
}
|
||
|
|
||
|
type MediaItemResponse {
|
||
|
data: [MediaItem]
|
||
|
page: PageResponse!
|
||
|
}
|
||
|
|
||
|
type UserResponse {
|
||
|
data: [User]
|
||
|
page: PageResponse!
|
||
|
}
|
||
|
|
||
|
type DeviceResponse {
|
||
|
data: [Device]
|
||
|
page: PageResponse!
|
||
|
}
|
||
|
|
||
|
type TagResponse {
|
||
|
data: [Tag]
|
||
|
page: PageResponse!
|
||
|
}
|
||
|
|
||
|
type AlbumResponse {
|
||
|
data: [Album]
|
||
|
page: PageResponse!
|
||
|
}
|
||
|
|
||
|
# ------------------------------------------------------------
|
||
|
# --------------------- Query & Mutations --------------------
|
||
|
# ------------------------------------------------------------
|
||
|
|
||
|
type Query {
|
||
|
# Authentication
|
||
|
login(
|
||
|
user: String!
|
||
|
password: String!
|
||
|
deviceID: ID
|
||
|
): AuthResponse!
|
||
|
logout: AuthResponse! @hasMinRole(role: User)
|
||
|
|
||
|
# Single Item
|
||
|
mediaItem(
|
||
|
id: ID!
|
||
|
): MediaItem! @hasMinRole(role: User)
|
||
|
device(
|
||
|
id: ID!
|
||
|
): Device! @hasMinRole(role: User)
|
||
|
album(
|
||
|
id: ID!
|
||
|
): Album! @hasMinRole(role: User)
|
||
|
user(
|
||
|
id: ID!
|
||
|
): User! @hasMinRole(role: Admin)
|
||
|
tag(
|
||
|
id: ID!
|
||
|
): Tag! @hasMinRole(role: User)
|
||
|
me: User! @hasMinRole(role: User)
|
||
|
|
||
|
# All
|
||
|
mediaItems(
|
||
|
filter: MediaItemFilter
|
||
|
page: Page
|
||
|
order: Order
|
||
|
): MediaItemResponse! @hasMinRole(role: User)
|
||
|
devices(
|
||
|
filter: DeviceFilter
|
||
|
page: Page
|
||
|
order: Order
|
||
|
): DeviceResponse! @hasMinRole(role: User)
|
||
|
albums(
|
||
|
filter: AlbumFilter
|
||
|
page: Page
|
||
|
order: Order
|
||
|
): AlbumResponse! @hasMinRole(role: User)
|
||
|
tags(
|
||
|
filter: TagFilter
|
||
|
page: Page
|
||
|
order: Order
|
||
|
): TagResponse! @hasMinRole(role: User)
|
||
|
users(
|
||
|
filter: UserFilter
|
||
|
page: Page
|
||
|
order: Order
|
||
|
): UserResponse! @hasMinRole(role: Admin)
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|