-
Notifications
You must be signed in to change notification settings - Fork 0
#266 Implement TournamentCompetitor details page #269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import { GenericDoc } from '@convex-dev/auth/server'; | ||||||||||||||||||||||||||||||||||||||||||
| import { SystemDataModel } from 'convex/server'; | ||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||
| ConvexError, | ||||||||||||||||||||||||||||||||||||||||||
| Infer, | ||||||||||||||||||||||||||||||||||||||||||
| v, | ||||||||||||||||||||||||||||||||||||||||||
| } from 'convex/values'; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { QueryCtx } from '../../../_generated/server'; | ||||||||||||||||||||||||||||||||||||||||||
| import { getErrorMessage } from '../../common/errors'; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| export const getFileMetadataArgs = v.object({ | ||||||||||||||||||||||||||||||||||||||||||
| id: v.id('_storage'), | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| export const getFileMetadata = async ( | ||||||||||||||||||||||||||||||||||||||||||
| ctx: QueryCtx, | ||||||||||||||||||||||||||||||||||||||||||
| args: Infer<typeof getFileMetadataArgs>, | ||||||||||||||||||||||||||||||||||||||||||
| ): Promise<GenericDoc<SystemDataModel,'_storage'> | null> => { | ||||||||||||||||||||||||||||||||||||||||||
| const fileMetadata = await ctx.db.system.get(args.id); | ||||||||||||||||||||||||||||||||||||||||||
| if (!fileMetadata) { | ||||||||||||||||||||||||||||||||||||||||||
| throw new ConvexError(getErrorMessage('FILE_NOT_FOUND')); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| return fileMetadata; | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return type includes The return type declares 🔎 Proposed fix: Remove `| null` from return type export const getFileMetadata = async (
ctx: QueryCtx,
args: Infer<typeof getFileMetadataArgs>,
-): Promise<GenericDoc<SystemDataModel,'_storage'> | null> => {
+): Promise<GenericDoc<SystemDataModel,'_storage'>> => {
const fileMetadata = await ctx.db.system.get(args.id);
if (!fileMetadata) {
throw new ConvexError(getErrorMessage('FILE_NOT_FOUND'));
}
return fileMetadata;
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||||||||||||||||||||||||||||||
| /* eslint-disable @typescript-eslint/no-unused-vars */ | ||||||||||||||||||||||||||||||||||||||||||
| import { GameSystem } from '@ianpaschal/combat-command-game-systems/common'; | ||||||||||||||||||||||||||||||||||||||||||
| import { ForceDiagram, Unit } from '@ianpaschal/combat-command-game-systems/flamesOfWarV4'; | ||||||||||||||||||||||||||||||||||||||||||
| import { Infer, v } from 'convex/values'; | ||||||||||||||||||||||||||||||||||||||||||
| import { customAlphabet } from 'nanoid'; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| import { ActionCtx, MutationCtx } from '../../../_generated/server'; | ||||||||||||||||||||||||||||||||||||||||||
| import { getStaticEnumConvexValidator } from '../../common/_helpers/getStaticEnumConvexValidator'; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const forceDiagram = getStaticEnumConvexValidator(ForceDiagram); | ||||||||||||||||||||||||||||||||||||||||||
| const formation = getStaticEnumConvexValidator(Unit); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 6); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stub implementation with unused imports. This file appears to be a placeholder with several unused imports (ForceDiagram, Unit, nanoid, validators). The If this is intentional scaffolding for future work, consider opening a follow-up issue to track the complete implementation. Would you like me to help generate a proper implementation based on the commented code below? 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
| export const extractListDataArgs = v.object({ | ||||||||||||||||||||||||||||||||||||||||||
| storageId: v.id('_storage'), | ||||||||||||||||||||||||||||||||||||||||||
| gameSystem: v.string(), | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| export const extractListData = async ( | ||||||||||||||||||||||||||||||||||||||||||
| ctx: ActionCtx, | ||||||||||||||||||||||||||||||||||||||||||
| args: Infer<typeof extractListDataArgs>, | ||||||||||||||||||||||||||||||||||||||||||
| ): Promise<{ fileType: string; data: Record<string, string> }> => | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // const fileMetadata = ctx.runQuery(); | ||||||||||||||||||||||||||||||||||||||||||
| ({ | ||||||||||||||||||||||||||||||||||||||||||
| fileType: 'foo', | ||||||||||||||||||||||||||||||||||||||||||
| data: { | ||||||||||||||||||||||||||||||||||||||||||
| foo: 'foo', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||
| ; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Stub implementation returns placeholder data. The The commented line 25 suggests a query should be executed. Please implement the actual data extraction logic before merging. 🔍 Verify usage of this action#!/bin/bash
# Description: Find all usages of extractListData to assess impact
# Search for extractListData imports and calls
rg -n --type=ts --type=tsx 'extractListData' -A 3 -B 1🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // gameSystem: GameSystem.FlamesOfWarV4, | ||||||||||||||||||||||||||||||||||||||||||
| // tournamentRegistrationId: | ||||||||||||||||||||||||||||||||||||||||||
| // // ownerUserId: row.playerUserId, | ||||||||||||||||||||||||||||||||||||||||||
| // // data: { | ||||||||||||||||||||||||||||||||||||||||||
| // // meta: { | ||||||||||||||||||||||||||||||||||||||||||
| // // forceDiagram: row.forceDiagram, | ||||||||||||||||||||||||||||||||||||||||||
| // // pointsLimit: args.pointsLimit, | ||||||||||||||||||||||||||||||||||||||||||
| // // }, | ||||||||||||||||||||||||||||||||||||||||||
| // // formations: row.formations.map((sourceId) => ({ | ||||||||||||||||||||||||||||||||||||||||||
| // // id: nanoid(), | ||||||||||||||||||||||||||||||||||||||||||
| // // sourceId, | ||||||||||||||||||||||||||||||||||||||||||
| // // })), | ||||||||||||||||||||||||||||||||||||||||||
| // // units: [], | ||||||||||||||||||||||||||||||||||||||||||
| // // commandCards: [], | ||||||||||||||||||||||||||||||||||||||||||
| // // }, | ||||||||||||||||||||||||||||||||||||||||||
| // // locked: args.locked, | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+34
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Remove or implement commented code. This large block of commented code suggests the intended implementation but reduces code maintainability. Consider either:
🔎 Suggested cleanup-// gameSystem: GameSystem.FlamesOfWarV4,
-// tournamentRegistrationId:
-// // ownerUserId: row.playerUserId,
-// // data: {
-// // meta: {
-// // forceDiagram: row.forceDiagram,
-// // pointsLimit: args.pointsLimit,
-// // },
-// // formations: row.formations.map((sourceId) => ({
-// // id: nanoid(),
-// // sourceId,
-// // })),
-// // units: [],
-// // commandCards: [],
-// // },
-// // locked: args.locked,
+// TODO: Implement data extraction logic
+// - Query file metadata using ctx.runQuery()
+// - Parse list data based on gameSystem
+// - Return structured data with appropriate fileType📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /* eslint-disable @typescript-eslint/no-unused-vars */ | ||
| import { Infer, v } from 'convex/values'; | ||
|
|
||
| import { ActionCtx } from '../../../_generated/server'; | ||
|
|
||
| export const importListArgs = v.object({ | ||
| url: v.string(), | ||
| gameSystem: v.string(), | ||
| }); | ||
|
|
||
| export const importList = async ( | ||
| ctx: ActionCtx, | ||
| args: Infer<typeof importListArgs>, | ||
| ): Promise<void> => { | ||
|
|
||
| const url = new URL(args.url); | ||
|
|
||
| // Extract basic components | ||
| const domain = url.hostname; // "example.com" | ||
| const protocol = url.protocol; // "https:" | ||
| const pathname = url.pathname; // "/users/550e8400-e29b-41d4-a801-146655440000" | ||
| const searchParams = url.searchParams; // URLSearchParams object | ||
|
|
||
| // Extract path segments | ||
| const pathSegments = url.pathname.split('/').filter(Boolean); | ||
| // ["users", "550e8400-e29b-41d4-a801-146655440000"] | ||
|
|
||
| // Extract UUID from path (if you know its position) | ||
| const uuid = pathSegments[1]; | ||
|
|
||
| // Or use regex to find UUID anywhere in the path | ||
| const uuidRegex = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i; | ||
| const match = url.pathname.match(uuidRegex); | ||
| const extractedUuid = match ? match[0] : null; | ||
|
|
||
| }; | ||
|
Comment on lines
+1
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Complete the stub implementation before merging. This action is incomplete and non-functional:
This stub should not be merged to main until the import logic is implemented. Do you want me to help implement the list import logic, or should this file be removed from the PR until the implementation is complete? 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,42 @@ | ||||||||||
| import { | ||||||||||
| ConvexError, | ||||||||||
| Infer, | ||||||||||
| v, | ||||||||||
| } from 'convex/values'; | ||||||||||
|
|
||||||||||
| import { Id } from '../../../_generated/dataModel'; | ||||||||||
| import { MutationCtx } from '../../../_generated/server'; | ||||||||||
| import { getErrorMessage } from '../../common/errors'; | ||||||||||
| import { editableFields } from '../table'; | ||||||||||
|
|
||||||||||
| // const forceDiagram = getStaticEnumConvexValidator(ForceDiagram); | ||||||||||
| // const formation = getStaticEnumConvexValidator(Unit); | ||||||||||
|
|
||||||||||
| // const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 6); | ||||||||||
|
Comment on lines
+12
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Remove commented-out code. These commented-out imports and code should be removed. If they're needed for future features, they can be restored from version control when required. 🔎 Proposed cleanup-// const forceDiagram = getStaticEnumConvexValidator(ForceDiagram);
-// const formation = getStaticEnumConvexValidator(Unit);
-
-// const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 6);
-📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| export const createListArgs = v.object(editableFields); | ||||||||||
|
|
||||||||||
| // TODO: Auto lock if after deadline | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Clarify or remove the TODO comment. The auto-locking logic appears to already be implemented on line 40, where 🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| export const createList = async ( | ||||||||||
| ctx: MutationCtx, | ||||||||||
| args: Infer<typeof createListArgs>, | ||||||||||
| ): Promise<Id<'lists'>> => { | ||||||||||
| if (!args.tournamentRegistrationId) { | ||||||||||
| throw new Error('Tournament registration required!'); // TODO: Remove once required | ||||||||||
| } | ||||||||||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Use ConvexError for consistency. For consistency with the error handling pattern used elsewhere in this function (lines 30, 34), consider using 🔎 Proposed fix if (!args.tournamentRegistrationId) {
- throw new Error('Tournament registration required!'); // TODO: Remove once required
+ throw new ConvexError(getErrorMessage('TOURNAMENT_REGISTRATION_REQUIRED'));
}Note: This assumes the error code 🤖 Prompt for AI Agents |
||||||||||
| const tournamentRegistration = await ctx.db.get(args.tournamentRegistrationId); | ||||||||||
| if (!tournamentRegistration) { | ||||||||||
| throw new ConvexError(getErrorMessage('TOURNAMENT_REGISTRATION_NOT_FOUND')); | ||||||||||
| } | ||||||||||
| const tournament = await ctx.db.get(tournamentRegistration.tournamentId); | ||||||||||
| if (!tournament) { | ||||||||||
| throw new ConvexError(getErrorMessage('TOURNAMENT_NOT_FOUND')); | ||||||||||
| } | ||||||||||
| const { listSubmissionClosesAt } = tournament; | ||||||||||
| return await ctx.db.insert('lists', { | ||||||||||
| ...args, | ||||||||||
| approvalStatus: null, | ||||||||||
| locked: Date.now() > listSubmissionClosesAt, | ||||||||||
| }); | ||||||||||
|
Comment on lines
+37
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify timing of the The 🤖 Prompt for AI Agents |
||||||||||
| }; | ||||||||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider using
find()instead offilter().pop().The current approach works but
find()is more idiomatic and slightly more efficient for getting a single element.🔎 Proposed refactor
📝 Committable suggestion
🤖 Prompt for AI Agents