feat: add shared card platform validation and diff utilities#63
Open
SdSarthak wants to merge 2 commits into
Open
feat: add shared card platform validation and diff utilities#63SdSarthak wants to merge 2 commits into
SdSarthak wants to merge 2 commits into
Conversation
- Add packages/shared/src/cards.ts with:
- validateCardPlatforms(platforms): checks all IDs exist in PLATFORMS,
no duplicates, max 10 per card; returns { valid, errors }
- diffCardPlatforms(oldCard, newCard): pure diff returning { added, removed, unchanged }
- CardValidationResult and CardDiffResult types
- Export from packages/shared/src/index.ts
- Add comprehensive vitest unit tests in packages/shared/src/__tests__/cards.test.ts
covering: empty arrays, unknown platforms, duplicates, max exceeded,
boundary (exactly 10), multiple errors, and all diff cases
- Add vitest as devDependency and "test" script to shared package.json
- Update apps/backend/src/routes/cards.ts to import validateCardPlatforms and
call it on both POST / (create) and PUT /:id (update) after resolving
PlatformLink records to their platform IDs, returning 400 with structured
errors on failure
Closes Dev-Card#31
There was a problem hiding this comment.
Pull request overview
Adds a shared cards utility module in @devcard/shared to validate card platform selections and compute platform diffs, then integrates the shared validator into backend card create/update routes.
Changes:
- Introduces
validateCardPlatformsanddiffCardPlatformsinpackages/shared/src/cards.tsand exports them frompackages/shared/src/index.ts. - Adds Vitest unit tests for the new shared utilities and wires up a
testscript for the shared package. - Updates backend
POST /andPUT /:idcard routes to validate requested platforms via the shared validator after resolvinglinkIdsto platform IDs.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/index.ts | Exports new shared card utilities. |
| packages/shared/src/cards.ts | Adds platform validation + platform diff utilities. |
| packages/shared/src/tests/cards.test.ts | Adds Vitest coverage for the new shared utilities. |
| packages/shared/package.json | Adds Vitest dependency and a shared-package test script. |
| apps/backend/src/routes/cards.ts | Uses shared platform validation when creating/updating card links. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| const seen = new Set<string>(); | ||
| for (const id of platforms) { | ||
| if (!PLATFORMS[id]) { |
Comment on lines
+63
to
+65
| const added = newCard.filter((id) => !oldSet.has(id)); | ||
| const removed = oldCard.filter((id) => !newSet.has(id)); | ||
| const unchanged = oldCard.filter((id) => newSet.has(id)); |
Comment on lines
+42
to
+53
| // Validate platform IDs via shared utility | ||
| if (parsed.data.linkIds.length > 0) { | ||
| const links = await app.prisma.platformLink.findMany({ | ||
| where: { id: { in: parsed.data.linkIds }, userId }, | ||
| select: { platform: true }, | ||
| }); | ||
| const platformIds = links.map((l) => l.platform); | ||
| const validation = validateCardPlatforms(platformIds); | ||
| if (!validation.valid) { | ||
| return reply.status(400).send({ error: 'Invalid card platforms', details: validation.errors }); | ||
| } | ||
| } |
Comment on lines
+115
to
+126
| // Validate updated platform set via shared utility | ||
| if (parsed.data.linkIds.length > 0) { | ||
| const links = await app.prisma.platformLink.findMany({ | ||
| where: { id: { in: parsed.data.linkIds }, userId }, | ||
| select: { platform: true }, | ||
| }); | ||
| const platformIds = links.map((l) => l.platform); | ||
| const validation = validateCardPlatforms(platformIds); | ||
| if (!validation.valid) { | ||
| return reply.status(400).send({ error: 'Invalid card platforms', details: validation.errors }); | ||
| } | ||
| } |
Comment on lines
+53
to
+57
| it('returns all platform IDs listed in PLATFORMS as valid', () => { | ||
| const known = ['github', 'linkedin', 'twitter', 'gitlab', 'devfolio', 'npm']; | ||
| const result = validateCardPlatforms(known); | ||
| expect(result.valid).toBe(true); | ||
| }); |
…lidate linkId ownership
Author
|
Thanks for the review — all three fixed in the follow-up commit:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the context-card diffing and validation layer described in the product doc (section 4.5), living in
packages/sharedso both web and mobile clients can use it.New:
packages/shared/src/cards.tsvalidateCardPlatforms(platforms: string[]): CardValidationResultPLATFORMS{ valid: boolean, errors: string[] }diffCardPlatforms(oldCard: string[], newCard: string[]): CardDiffResult{ added: string[], removed: string[], unchanged: string[] }Both are exported from
packages/shared/src/index.ts.Tests:
packages/shared/src/__tests__/cards.test.ts16 vitest unit tests covering:
Backend:
apps/backend/src/routes/cards.tsUpdated
POST /(create card) andPUT /:id(update card) to:linkIdsto theirplatformfields via PrismavalidateCardPlatforms(platformIds)from shared400 { error: 'Invalid card platforms', details: [...] }on failurePackage changes
Added
vitest ^2.0.0and"test": "vitest run"topackages/shared/package.json.Closes #31
Test plan
pnpm --filter @devcard/shared test— all 16 tests passpnpm -r typecheckpasses