diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index 3ef653ab..b8986f7d 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -32,12 +32,15 @@ import type * as _model_fowV4_divideFowV4BaseStats from "../_model/fowV4/divideF import type * as _model_fowV4_extractFowV4MatchResultBaseStats from "../_model/fowV4/extractFowV4MatchResultBaseStats.js"; import type * as _model_fowV4_flattenFowV4StatMap from "../_model/fowV4/flattenFowV4StatMap.js"; import type * as _model_fowV4_fowV4GameSystemConfig from "../_model/fowV4/fowV4GameSystemConfig.js"; +import type * as _model_fowV4_fowV4ListData from "../_model/fowV4/fowV4ListData.js"; import type * as _model_fowV4_fowV4MatchOutcomeType from "../_model/fowV4/fowV4MatchOutcomeType.js"; import type * as _model_fowV4_fowV4MatchResultDetails from "../_model/fowV4/fowV4MatchResultDetails.js"; import type * as _model_fowV4_getMission from "../_model/fowV4/getMission.js"; import type * as _model_fowV4_getMissionPack from "../_model/fowV4/getMissionPack.js"; import type * as _model_fowV4_sumFowV4BaseStats from "../_model/fowV4/sumFowV4BaseStats.js"; import type * as _model_fowV4_types from "../_model/fowV4/types.js"; +import type * as _model_lists_fields from "../_model/lists/fields.js"; +import type * as _model_lists_index from "../_model/lists/index.js"; import type * as _model_matchResultComments__helpers_deepenMatchResultComment from "../_model/matchResultComments/_helpers/deepenMatchResultComment.js"; import type * as _model_matchResultComments_fields from "../_model/matchResultComments/fields.js"; import type * as _model_matchResultComments_index from "../_model/matchResultComments/index.js"; @@ -223,12 +226,15 @@ declare const fullApi: ApiFromModules<{ "_model/fowV4/extractFowV4MatchResultBaseStats": typeof _model_fowV4_extractFowV4MatchResultBaseStats; "_model/fowV4/flattenFowV4StatMap": typeof _model_fowV4_flattenFowV4StatMap; "_model/fowV4/fowV4GameSystemConfig": typeof _model_fowV4_fowV4GameSystemConfig; + "_model/fowV4/fowV4ListData": typeof _model_fowV4_fowV4ListData; "_model/fowV4/fowV4MatchOutcomeType": typeof _model_fowV4_fowV4MatchOutcomeType; "_model/fowV4/fowV4MatchResultDetails": typeof _model_fowV4_fowV4MatchResultDetails; "_model/fowV4/getMission": typeof _model_fowV4_getMission; "_model/fowV4/getMissionPack": typeof _model_fowV4_getMissionPack; "_model/fowV4/sumFowV4BaseStats": typeof _model_fowV4_sumFowV4BaseStats; "_model/fowV4/types": typeof _model_fowV4_types; + "_model/lists/fields": typeof _model_lists_fields; + "_model/lists/index": typeof _model_lists_index; "_model/matchResultComments/_helpers/deepenMatchResultComment": typeof _model_matchResultComments__helpers_deepenMatchResultComment; "_model/matchResultComments/fields": typeof _model_matchResultComments_fields; "_model/matchResultComments/index": typeof _model_matchResultComments_index; diff --git a/convex/_model/fowV4/fowV4ListData.ts b/convex/_model/fowV4/fowV4ListData.ts new file mode 100644 index 00000000..e9243b16 --- /dev/null +++ b/convex/_model/fowV4/fowV4ListData.ts @@ -0,0 +1,27 @@ +import { v } from 'convex/values'; + +import { fowV4FactionId } from '../../static/fowV4/factions'; + +export const fowV4ListData = v.object({ + meta: v.object({ + alignment: v.union(v.literal('axis'), v.literal('allies')), + faction: fowV4FactionId, + diagram: v.string(), + points: v.number(), + }), + formations: v.array(v.object({ + id: v.string(), + sourceId: v.string(), + })), + units: v.array(v.object({ + id: v.string(), + sourceId: v.string(), + formationId: v.string(), // Formation ID or 'support' + slotId: v.string(), // e.g. Armour 1 + })), + commandCards: v.array(v.object({ + id: v.string(), + sourceId: v.string(), + appliedTo: v.string(), // Formation ID or unit ID + })), +}); diff --git a/convex/_model/lists/fields.ts b/convex/_model/lists/fields.ts new file mode 100644 index 00000000..8896fdea --- /dev/null +++ b/convex/_model/lists/fields.ts @@ -0,0 +1,18 @@ +import { v } from 'convex/values'; + +import { gameSystemId } from '../../static/gameSystems'; +import { fowV4ListData } from '../fowV4/fowV4ListData'; + +export const editableFields = { + gameSystemId: gameSystemId, + data: fowV4ListData, + ownerUserId: v.id('users'), +}; + +/** + * Fields which can only be edited using special mutations, or which are set programmatically. + */ +export const computedFields = { + modifiedAt: v.optional(v.number()), + locked: v.optional(v.boolean()), +}; diff --git a/convex/_model/lists/index.ts b/convex/_model/lists/index.ts new file mode 100644 index 00000000..9e0887ee --- /dev/null +++ b/convex/_model/lists/index.ts @@ -0,0 +1,12 @@ +import { defineTable } from 'convex/server'; + +import { Id } from '../../_generated/dataModel'; +import { computedFields, editableFields } from './fields'; + +export const listsTable = defineTable({ + ...editableFields, + ...computedFields, +}) + .index('by_owner_user_id', ['ownerUserId']); + +export type ListId = Id<'lists'>; diff --git a/convex/_model/tournamentCompetitors/fields.ts b/convex/_model/tournamentCompetitors/fields.ts index 99743590..6153e490 100644 --- a/convex/_model/tournamentCompetitors/fields.ts +++ b/convex/_model/tournamentCompetitors/fields.ts @@ -6,6 +6,7 @@ export const editableFields = { players: v.array(v.object({ userId: v.id('users'), active: v.boolean(), + listId: v.optional(v.id('lists')), })), }; diff --git a/convex/schema.ts b/convex/schema.ts index d5a8102a..1c0bcd17 100644 --- a/convex/schema.ts +++ b/convex/schema.ts @@ -1,6 +1,7 @@ import { authTables } from '@convex-dev/auth/server'; import { defineSchema } from 'convex/server'; +import { listsTable } from './_model/lists'; import { matchResultCommentsTable } from './_model/matchResultComments'; import { matchResultLikesTable } from './_model/matchResultLikes'; import { matchResultsTable } from './_model/matchResults'; @@ -15,6 +16,7 @@ import { photos } from './photos'; export default defineSchema({ ...authTables, friendships, + lists: listsTable, matchResultComments: matchResultCommentsTable, matchResultLikes: matchResultLikesTable, matchResults: matchResultsTable,