diff --git a/backend/functions/migration.ts b/backend/functions/migration.ts index 5f02398..4259202 100644 --- a/backend/functions/migration.ts +++ b/backend/functions/migration.ts @@ -64,7 +64,7 @@ export async function up(knex: Knex): Promise { table.integer("attempts_succeeded").nullable(); table.integer("attempts_total").nullable(); table.integer("product").nullable(); - table.dateTime("happened_on").notNullable(); + table.dateTime("happened_on").nullable(); table.integer("time_elapsed").nullable(); table.decimal("moves_count").nullable(); table.boolean("is_current").notNullable(); diff --git a/backend/functions/schema.ts b/backend/functions/schema.ts index 3a82b9d..0b95606 100644 --- a/backend/functions/schema.ts +++ b/backend/functions/schema.ts @@ -330,7 +330,7 @@ export type FilterByField = { attemptsSucceeded?: Scalars["number"] | null; attemptsTotal?: Scalars["number"] | null; product?: InputTypes["product"] | null; - happenedOn: Scalars["unixTimestamp"]; + happenedOn?: Scalars["unixTimestamp"] | null; timeElapsed?: Scalars["number"] | null; movesCount?: Scalars["number"] | null; publicComments?: Scalars["string"] | null; @@ -342,7 +342,7 @@ export type FilterByField = { attemptsSucceeded?: Scalars["number"] | null; attemptsTotal?: Scalars["number"] | null; product?: InputTypes["product"] | null; - happenedOn?: Scalars["unixTimestamp"]; + happenedOn?: Scalars["unixTimestamp"] | null; timeElapsed?: Scalars["number"] | null; movesCount?: Scalars["number"] | null; publicComments?: Scalars["string"] | null; @@ -353,7 +353,11 @@ export type FilterByField = { }; apiKey: { id?: Scalars["id"] }; "apiKeyFilterByField/id": FilterByField; - apiKeyFilterByObject: { id?: InputTypes["apiKeyFilterByField/id"] }; + "apiKeyFilterByField/user.id": FilterByField; + apiKeyFilterByObject: { + id?: InputTypes["apiKeyFilterByField/id"]; + "user.id"?: InputTypes["apiKeyFilterByField/user.id"]; + }; apiKeyPaginator: { first?: Scalars["number"]; last?: Scalars["number"]; @@ -686,7 +690,7 @@ export type UserUserFollowLinkEdge = Edge; Args: undefined; }; product: { Type: Product | null; Args: undefined }; - happenedOn: { Type: Scalars["unixTimestamp"]; Args: undefined }; + happenedOn: { Type: Scalars["unixTimestamp"] | null; Args: undefined }; /**The amount of ms time elapsed for the pb attempt*/ timeElapsed: { Type: Scalars["number"] | null; Args: undefined; diff --git a/backend/functions/src/helpers/auth.ts b/backend/functions/src/helpers/auth.ts index 4a2f9a3..d57621e 100644 --- a/backend/functions/src/helpers/auth.ts +++ b/backend/functions/src/helpers/auth.ts @@ -135,7 +135,6 @@ export async function validateApiKey(auth: string): Promise { permissions: finalPermissions, }; } catch (err) { - console.log(err); const message = "Token error: " + (err.message || err.name); throw new Error(message); } diff --git a/backend/functions/src/schema/models/personalBest/service.ts b/backend/functions/src/schema/models/personalBest/service.ts index f76055d..68bd4a8 100644 --- a/backend/functions/src/schema/models/personalBest/service.ts +++ b/backend/functions/src/schema/models/personalBest/service.ts @@ -136,6 +136,11 @@ export class PersonalBestService extends PaginatedService { // args should be validated already const validatedArgs = args; + // if happenedOn is null, set it to current unix timestamp + if (!validatedArgs.happenedOn) { + validatedArgs.happenedOn = new Date().getTime() / 1000; + } + // get event.scoreMethod const eventRecords = await sqlHelper.fetchTableRows({ select: [ diff --git a/backend/functions/src/schema/models/personalBest/typeDef.ts b/backend/functions/src/schema/models/personalBest/typeDef.ts index f1773c3..9dae9d9 100644 --- a/backend/functions/src/schema/models/personalBest/typeDef.ts +++ b/backend/functions/src/schema/models/personalBest/typeDef.ts @@ -21,6 +21,7 @@ import { } from "../../core/helpers/typeDef"; import * as Scalars from "../../scalars"; import * as Resolver from "../../core/helpers/resolver"; +import { knex } from "../../../utils/knex"; export default new GiraffeqlObjectType({ name: PersonalBest.typename, @@ -65,6 +66,7 @@ export default new GiraffeqlObjectType({ }), happenedOn: generateUnixTimestampField({ allowNull: false, + defaultValue: knex.fn.now(), // not really setting via DB. default is calculated manually in the createRecord function sqlOptions: { field: "happened_on" }, }), timeElapsed: generateIntegerField({ diff --git a/frontend/models/personalBest.ts b/frontend/models/personalBest.ts index 6f9a912..716bce6 100644 --- a/frontend/models/personalBest.ts +++ b/frontend/models/personalBest.ts @@ -172,11 +172,12 @@ export const PersonalBest = >{ }, happenedOn: { text: 'Date Happened', + optional: true, hint: - 'To specify the exact date and time, use format: YYYY-MM-DD 1:23 PM', + 'Leave this blank to set to current date. To specify the exact date and time, use format: YYYY-MM-DD 1:23 PM', inputType: 'datepicker', // default to today. - default: () => { + /* default: () => { const date = new Date() return ( date.getFullYear() + @@ -185,14 +186,14 @@ export const PersonalBest = >{ '-' + String(date.getDate()).padStart(2, '0') ) - }, + }, */ // unix timestamp to YYYY-MM-DD serialize: (val: number) => val && new Date(val * 1000).toISOString().substring(0, 10), // YYYY-MM-DD to unix timestamp parseValue: (val: string) => { // null or falsey values not allowed - if (!val) throw new Error(`Invalid value for Date Happened`) + if (!val) return undefined const msTimestamp = new Date(val).getTime() // date cannot be to far in the future diff --git a/frontend/pages/my-apps.vue b/frontend/pages/my-apps.vue index 9f8d6e3..99d5433 100644 --- a/frontend/pages/my-apps.vue +++ b/frontend/pages/my-apps.vue @@ -22,7 +22,7 @@ . The API Key needs to be passed as a header with the key x-api-key . The request body must be sent as JSON. Official documentation of - all the API functiaonlity is not currently available, but you can + all the API functionality is not currently available, but you can see what the JSON body looks like for various kinds of actions by looking at the Request Payload in the developer console of your browser while performing those actions on the site. For help