Skip to content

Commit 1a43e0e

Browse files
committed
chore: fix prettier formatting and expand lint-staged config
- Auto-format all files with prettier - Expand lint-staged to cover convex/**, *.md, *.html, *.json - Prevent future CI format check failures
1 parent 3342521 commit 1a43e0e

18 files changed

Lines changed: 349 additions & 191 deletions

File tree

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
"packages/*"
88
],
99
"lint-staged": {
10-
"packages/site/src/**/*.{ts,tsx}": [
10+
"packages/site/**/*.{ts,tsx}": [
1111
"bash -c 'cd packages/site && bun run typecheck'",
1212
"bunx prettier --write"
1313
],
14-
"packages/site/src/**/*.{js,jsx,css,json}": [
14+
"packages/site/**/*.{js,jsx,css,json,md,html}": [
1515
"bunx prettier --write"
1616
],
17-
"packages/gql/src/**/*.{ts,graphql}": [
17+
"packages/gql/**/*.{ts,graphql}": [
18+
"bunx prettier --write"
19+
],
20+
"*.{md,json}": [
1821
"bunx prettier --write"
1922
]
2023
},

packages/site/REFACTORING_GUIDE.md

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
# Navigation Refactoring Guide
22

33
## Problem
4+
45
Navigation structure is hardcoded in `src/pages/docs/index.tsx`, violating SSOT principle and making maintenance difficult.
56

67
## Solution
8+
79
Created `src/lib/navigation.ts` as Single Source of Truth for all navigation items.
810

911
## Before (Hardcoded)
12+
1013
```tsx
1114
<MenuDropdown
1215
title="APIs"
@@ -23,53 +26,66 @@ Created `src/lib/navigation.ts` as Single Source of Truth for all navigation ite
2326
```
2427

2528
## After (Config-driven)
29+
2630
```tsx
27-
import { REFERENCE_NAV, TUTORIAL_NAV, SIMPLE_NAV_LINKS } from "../../lib/navigation";
31+
import {
32+
REFERENCE_NAV,
33+
TUTORIAL_NAV,
34+
SIMPLE_NAV_LINKS,
35+
} from "../../lib/navigation";
2836

2937
// In component:
30-
{REFERENCE_NAV.map((section) => (
31-
<MenuDropdown
32-
key={section.title}
33-
title={section.title}
34-
titleTo={section.titleTo}
35-
items={section.items}
36-
onItemClick={closeSidebar}
37-
isExpanded={expandedReference === section.title.toLowerCase()}
38-
onToggle={() => handleReferenceToggle(section.title.toLowerCase())}
39-
/>
40-
))}
38+
{
39+
REFERENCE_NAV.map((section) => (
40+
<MenuDropdown
41+
key={section.title}
42+
title={section.title}
43+
titleTo={section.titleTo}
44+
items={section.items}
45+
onItemClick={closeSidebar}
46+
isExpanded={expandedReference === section.title.toLowerCase()}
47+
onToggle={() => handleReferenceToggle(section.title.toLowerCase())}
48+
/>
49+
));
50+
}
4151
```
4252

4353
## Benefits
4454

4555
### ✅ SSOT Compliance
56+
4657
- All navigation items defined in one place
4758
- Easy to add/remove/update items
4859
- No duplication
4960

5061
### ✅ Type Safety
62+
5163
- Full TypeScript support
5264
- Compile-time validation
5365
- Autocomplete in IDE
5466

5567
### ✅ Maintainability
68+
5669
- Changes in one place affect entire app
5770
- Easy to refactor route structure
5871
- Clear separation of concerns
5972

6073
### ✅ Scalability
74+
6175
- Easy to add new sections
6276
- Supports dynamic navigation
6377
- Can extend for i18n, permissions, etc.
6478

6579
## Migration Steps
6680

6781
1. **Import config**:
82+
6883
```tsx
6984
import { REFERENCE_NAV, TUTORIAL_NAV } from "../../lib/navigation";
7085
```
7186

7287
2. **Replace Reference section**:
88+
7389
```tsx
7490
<h3 style={{ marginTop: "2rem" }}>Reference</h3>
7591
<ul>
@@ -119,56 +135,62 @@ import { REFERENCE_NAV, TUTORIAL_NAV, SIMPLE_NAV_LINKS } from "../../lib/navigat
119135
## Future Enhancements
120136

121137
### Dynamic Navigation
138+
122139
```tsx
123140
// navigation.ts
124141
export const getNavigationForUser = (userRole: string) => {
125-
return REFERENCE_NAV.filter(section =>
142+
return REFERENCE_NAV.filter((section) =>
126143
hasPermission(userRole, section.title)
127144
);
128145
};
129146
```
130147

131148
### Internationalization
149+
132150
```tsx
133151
// navigation.ts
134152
export const getLocalizedNav = (locale: string) => {
135-
return REFERENCE_NAV.map(section => ({
153+
return REFERENCE_NAV.map((section) => ({
136154
...section,
137155
title: t(section.title, { locale }),
138-
items: section.items.map(item => ({
156+
items: section.items.map((item) => ({
139157
...item,
140-
label: t(item.label, { locale })
141-
}))
158+
label: t(item.label, { locale }),
159+
})),
142160
}));
143161
};
144162
```
145163

146164
### Search Integration
165+
147166
```tsx
148167
// All nav items flattened for search
149168
export const getAllNavItems = () => [
150-
...REFERENCE_NAV.flatMap(s => s.items),
151-
...TUTORIAL_NAV.flatMap(s => s.items),
169+
...REFERENCE_NAV.flatMap((s) => s.items),
170+
...TUTORIAL_NAV.flatMap((s) => s.items),
152171
...SIMPLE_NAV_LINKS,
153172
];
154173
```
155174

156175
## Testing
157-
```tsx
158-
import { REFERENCE_NAV, TUTORIAL_NAV } from '../lib/navigation';
159176

160-
describe('Navigation Config', () => {
161-
it('should have valid routes', () => {
162-
const allItems = [...REFERENCE_NAV, ...TUTORIAL_NAV].flatMap(s => s.items);
163-
allItems.forEach(item => {
177+
```tsx
178+
import { REFERENCE_NAV, TUTORIAL_NAV } from "../lib/navigation";
179+
180+
describe("Navigation Config", () => {
181+
it("should have valid routes", () => {
182+
const allItems = [...REFERENCE_NAV, ...TUTORIAL_NAV].flatMap(
183+
(s) => s.items
184+
);
185+
allItems.forEach((item) => {
164186
expect(item.to).toMatch(/^\/docs\//);
165187
});
166188
});
167189

168-
it('should have unique labels', () => {
190+
it("should have unique labels", () => {
169191
const labels = [...REFERENCE_NAV, ...TUTORIAL_NAV]
170-
.flatMap(s => s.items)
171-
.map(i => i.label);
192+
.flatMap((s) => s.items)
193+
.map((i) => i.label);
172194
const unique = new Set(labels);
173195
expect(labels.length).toBe(unique.size);
174196
});

packages/site/convex/comments/mutation.ts

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,18 @@ export const addComment = mutation({
4040
.withIndex("by_user", (q) => q.eq("userId", userId))
4141
.first();
4242

43-
await ctx.runMutation(internal.notifications.mutation.createNotification, {
44-
userId: post.authorId,
45-
type: "COMMENT_ON_POST",
46-
title: "New Comment",
47-
message: `${commenterProfile?.displayName || commenterProfile?.githubUsername || "Someone"} commented on your post "${post.title}"`,
48-
postId: args.postId,
49-
commentId,
50-
triggeredById: userId,
51-
});
43+
await ctx.runMutation(
44+
internal.notifications.mutation.createNotification,
45+
{
46+
userId: post.authorId,
47+
type: "COMMENT_ON_POST",
48+
title: "New Comment",
49+
message: `${commenterProfile?.displayName || commenterProfile?.githubUsername || "Someone"} commented on your post "${post.title}"`,
50+
postId: args.postId,
51+
commentId,
52+
triggeredById: userId,
53+
}
54+
);
5255
}
5356

5457
// If this is a reply, notify the parent comment author
@@ -60,20 +63,27 @@ export const addComment = mutation({
6063
.withIndex("by_user", (q) => q.eq("userId", userId))
6164
.first();
6265

63-
await ctx.runMutation(internal.notifications.mutation.createNotification, {
64-
userId: parentComment.authorId,
65-
type: "COMMENT_ON_POST",
66-
title: "New Reply",
67-
message: `${commenterProfile?.displayName || commenterProfile?.githubUsername || "Someone"} replied to your comment`,
68-
postId: args.postId,
69-
commentId,
70-
triggeredById: userId,
71-
});
66+
await ctx.runMutation(
67+
internal.notifications.mutation.createNotification,
68+
{
69+
userId: parentComment.authorId,
70+
type: "COMMENT_ON_POST",
71+
title: "New Reply",
72+
message: `${commenterProfile?.displayName || commenterProfile?.githubUsername || "Someone"} replied to your comment`,
73+
postId: args.postId,
74+
commentId,
75+
triggeredById: userId,
76+
}
77+
);
7278
}
7379
}
7480

7581
// Send notifications to mentioned users
76-
const mentionedUserIds = await getMentionedUserIds(ctx.db, args.content, userId);
82+
const mentionedUserIds = await getMentionedUserIds(
83+
ctx.db,
84+
args.content,
85+
userId
86+
);
7787
// Filter out users who already received notifications (post author, parent comment author)
7888
const alreadyNotified = new Set([post.authorId]);
7989
if (args.parentId) {
@@ -85,19 +95,25 @@ export const addComment = mutation({
8595
.query("userProfiles")
8696
.withIndex("by_user", (q) => q.eq("userId", userId))
8797
.first();
88-
const commenterName = commenterProfile?.displayName || commenterProfile?.githubUsername || "Someone";
98+
const commenterName =
99+
commenterProfile?.displayName ||
100+
commenterProfile?.githubUsername ||
101+
"Someone";
89102

90103
for (const mentionedUserId of mentionedUserIds) {
91104
if (!alreadyNotified.has(mentionedUserId)) {
92-
await ctx.runMutation(internal.notifications.mutation.createNotification, {
93-
userId: mentionedUserId,
94-
type: "MENTIONED",
95-
title: "You were mentioned",
96-
message: `${commenterName} mentioned you in a comment on "${post.title}"`,
97-
postId: args.postId,
98-
commentId,
99-
triggeredById: userId,
100-
});
105+
await ctx.runMutation(
106+
internal.notifications.mutation.createNotification,
107+
{
108+
userId: mentionedUserId,
109+
type: "MENTIONED",
110+
title: "You were mentioned",
111+
message: `${commenterName} mentioned you in a comment on "${post.title}"`,
112+
postId: args.postId,
113+
commentId,
114+
triggeredById: userId,
115+
}
116+
);
101117
}
102118
}
103119

@@ -162,7 +178,10 @@ export const deleteComment = mutation({
162178
// Update post comment count
163179
if (post) {
164180
await ctx.db.patch(post._id, {
165-
commentsCount: Math.max(0, post.commentsCount - 1 - childReplies.length),
181+
commentsCount: Math.max(
182+
0,
183+
post.commentsCount - 1 - childReplies.length
184+
),
166185
});
167186
}
168187

@@ -183,7 +202,10 @@ export const toggleCommentLike = mutation({
183202
const existingLike = await ctx.db
184203
.query("likes")
185204
.withIndex("by_target_user", (q) =>
186-
q.eq("targetType", "comment").eq("targetId", args.commentId).eq("userId", userId)
205+
q
206+
.eq("targetType", "comment")
207+
.eq("targetId", args.commentId)
208+
.eq("userId", userId)
187209
)
188210
.first();
189211

@@ -213,15 +235,18 @@ export const toggleCommentLike = mutation({
213235
.withIndex("by_user", (q) => q.eq("userId", userId))
214236
.first();
215237

216-
await ctx.runMutation(internal.notifications.mutation.createNotification, {
217-
userId: comment.authorId,
218-
type: "LIKE_ON_COMMENT",
219-
title: "New Like",
220-
message: `${likerProfile?.displayName || likerProfile?.githubUsername || "Someone"} liked your comment`,
221-
postId: comment.postId,
222-
commentId: args.commentId,
223-
triggeredById: userId,
224-
});
238+
await ctx.runMutation(
239+
internal.notifications.mutation.createNotification,
240+
{
241+
userId: comment.authorId,
242+
type: "LIKE_ON_COMMENT",
243+
title: "New Like",
244+
message: `${likerProfile?.displayName || likerProfile?.githubUsername || "Someone"} liked your comment`,
245+
postId: comment.postId,
246+
commentId: args.commentId,
247+
triggeredById: userId,
248+
}
249+
);
225250
}
226251

227252
return { liked: true };

packages/site/convex/comments/query.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ export const getComments = query({
3636
const like = await ctx.db
3737
.query("likes")
3838
.withIndex("by_target_user", (q) =>
39-
q.eq("targetType", "comment").eq("targetId", comment._id).eq("userId", userId)
39+
q
40+
.eq("targetType", "comment")
41+
.eq("targetId", comment._id)
42+
.eq("userId", userId)
4043
)
4144
.first();
4245
hasLiked = !!like;
@@ -46,7 +49,10 @@ export const getComments = query({
4649
const githubUsername =
4750
authorProfile?.githubUsername || authorUser?.name || "user";
4851
const displayName =
49-
authorProfile?.displayName || authorProfile?.githubUsername || authorUser?.name || "Anonymous";
52+
authorProfile?.displayName ||
53+
authorProfile?.githubUsername ||
54+
authorUser?.name ||
55+
"Anonymous";
5056
const avatarUrl =
5157
authorProfile?.avatarUrl || authorUser?.image || undefined;
5258

@@ -70,9 +76,7 @@ export const getComments = query({
7076

7177
const commentsWithReplies = parentComments.map((parent) => ({
7278
...parent,
73-
replies: childComments.filter(
74-
(child) => child.parentId === parent._id
75-
),
79+
replies: childComments.filter((child) => child.parentId === parent._id),
7680
}));
7781

7882
return commentsWithReplies;

packages/site/convex/lemon_squeezy/webhook.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ export const webhook = httpAction(async (ctx, request) => {
178178
if (githubUsername && membershipId) {
179179
const githubToken = process.env.GITHUB_REPO_ADMIN_TOKEN;
180180
if (githubToken) {
181-
const inviteSent = await addRepoCollaborator(githubUsername, githubToken);
181+
const inviteSent = await addRepoCollaborator(
182+
githubUsername,
183+
githubToken
184+
);
182185
if (inviteSent) {
183186
await ctx.runMutation(internal.pro.mutation.markGithubInviteSent, {
184187
membershipId,

0 commit comments

Comments
 (0)