Skip to content

Commit d92bd0d

Browse files
author
Marvin Zhang
committed
feat: update routing to use name-based identifiers for projects and devlogs, enhancing URL clarity and consistency
1 parent 7f6558d commit d92bd0d

File tree

15 files changed

+110
-187
lines changed

15 files changed

+110
-187
lines changed

packages/web/ROUTING.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,33 @@
22

33
## Overview
44

5-
The web package uses Next.js 14 App Router with hierarchical routing structure that matches the API endpoints. This provides better organization and clearer URL structure for project-scoped operations.
5+
The web package uses Next.js 14 App Router with hierarchical routing structure that matches the API endpoints. This
6+
provides better organization and clearer URL structure for project-scoped operations.
67

78
## Route Structure
89

910
### Hierarchical Project-Based Routes (Primary)
11+
1012
```
1113
/ - Dashboard (homepage)
1214
/projects - Project management page
13-
/projects/[id] - Project details page
14-
/projects/[id]/devlogs - List of devlogs for specific project
15-
/projects/[id]/devlogs/create - Create new devlog in specific project
16-
/projects/[id]/devlogs/[devlogId] - Individual devlog details within project
15+
/projects/[name] - Project details page
16+
/projects/[name]/devlogs - List of devlogs for specific project
17+
/projects/[name]/devlogs/[id] - Individual devlog details within project
1718
```
1819

1920
````markdown
2021
# Routing Implementation for @codervisor/devlog-web
2122

2223
## Overview
2324

24-
The web package uses Next.js 14 App Router with hierarchical routing structure that matches the API endpoints. This provides better organization and clearer URL structure for project-scoped operations.
25+
The web package uses Next.js 14 App Router with hierarchical routing structure that matches the API endpoints. This
26+
provides better organization and clearer URL structure for project-scoped operations.
2527

2628
## Route Structure
2729

2830
### Hierarchical Project-Based Routes (Primary)
31+
2932
```
3033
/ - Redirects to /projects
3134
/projects - Project list page (main entry point)
@@ -38,11 +41,14 @@ The web package uses Next.js 14 App Router with hierarchical routing structure t
3841
## Key Changes Made
3942

4043
### Route Purpose Updates
44+
4145
- **`/` (Homepage)**: Now redirects to `/projects` as the main entry point
4246
- **`/projects`**: Project list/management page - browse and manage all projects
43-
- **`/projects/[id]`**: Project dashboard - overview with stats, charts, and recent devlogs (formerly the homepage dashboard)
47+
- **`/projects/[id]`**: Project dashboard - overview with stats, charts, and recent devlogs (formerly the homepage
48+
dashboard)
4449

4550
### Navigation Flow
51+
4652
1. **User visits `/`** → Automatically redirected to `/projects`
4753
2. **User browses projects** at `/projects` → Can view all projects and create new ones
4854
3. **User selects a project** → Goes to `/projects/[id]` for that project's dashboard
@@ -79,16 +85,19 @@ app/
7985
## Component Responsibilities
8086

8187
### ProjectManagementPage (/projects)
88+
8289
- **Primary function**: Project list and management interface
8390
- **Features**: Browse projects, create new projects, view project cards
8491
- **Navigation**: Links to individual project dashboards
8592

8693
### ProjectDetailsPage (/projects/[id])
94+
8795
- **Primary function**: Project-specific dashboard and overview
8896
- **Features**: Project stats, time series charts, recent devlogs, overview stats
8997
- **Context**: Sets project context for the entire project section
9098

9199
### DashboardPage Component
100+
92101
- **Usage**: Embedded in ProjectDetailsPage for project-specific dashboards
93102
- **Features**: Stats visualization, time series data, recent devlogs display
94103
- **Scope**: Project-scoped rather than global

packages/web/app/api/projects/[name]/devlogs/[devlogId]/notes/[noteId]/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const UpdateNoteBodySchema = z.object({
1414
category: z.string().optional(),
1515
});
1616

17-
// GET /api/projects/[name]/devlogs/[devlogId]/notes/[noteId] - Get specific note
17+
// GET /api/projects/[name]/devlogs/[id]/notes/[noteId] - Get specific note
1818
export async function GET(
1919
request: NextRequest,
2020
{ params }: { params: { name: string; devlogId: string; noteId: string } },
@@ -53,7 +53,7 @@ export async function GET(
5353
}
5454
}
5555

56-
// PUT /api/projects/[name]/devlogs/[devlogId]/notes/[noteId] - Update specific note
56+
// PUT /api/projects/[name]/devlogs/[id]/notes/[noteId] - Update specific note
5757
export async function PUT(
5858
request: NextRequest,
5959
{ params }: { params: { name: string; devlogId: string; noteId: string } },
@@ -106,7 +106,7 @@ export async function PUT(
106106
}
107107
}
108108

109-
// DELETE /api/projects/[name]/devlogs/[devlogId]/notes/[noteId] - Delete specific note
109+
// DELETE /api/projects/[name]/devlogs/[id]/notes/[noteId] - Delete specific note
110110
export async function DELETE(
111111
request: NextRequest,
112112
{ params }: { params: { name: string; devlogId: string; noteId: string } },

packages/web/app/api/projects/[name]/devlogs/[devlogId]/notes/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { DevlogAddNoteBodySchema, DevlogUpdateWithNoteBodySchema } from '@/schem
88
// Mark this route as dynamic to prevent static generation
99
export const dynamic = 'force-dynamic';
1010

11-
// GET /api/projects/[name]/devlogs/[devlogId]/notes - List notes for a devlog entry
11+
// GET /api/projects/[name]/devlogs/[id]/notes - List notes for a devlog entry
1212
export async function GET(
1313
request: NextRequest,
1414
{ params }: { params: { name: string; devlogId: string } },
@@ -68,7 +68,7 @@ export async function GET(
6868
}
6969
}
7070

71-
// POST /api/projects/[name]/devlogs/[devlogId]/notes - Add note to devlog entry
71+
// POST /api/projects/[name]/devlogs/[id]/notes - Add note to devlog entry
7272
export async function POST(
7373
request: NextRequest,
7474
{ params }: { params: { name: string; devlogId: string } },
@@ -118,7 +118,7 @@ export async function POST(
118118
}
119119
}
120120

121-
// PUT /api/projects/[name]/devlogs/[devlogId]/notes - Update devlog and add note in one operation
121+
// PUT /api/projects/[name]/devlogs/[id]/notes - Update devlog and add note in one operation
122122
export async function PUT(
123123
request: NextRequest,
124124
{ params }: { params: { name: string; devlogId: string } },

packages/web/app/api/projects/[name]/devlogs/[devlogId]/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { RealtimeEventType } from '@/lib/realtime';
66
// Mark this route as dynamic to prevent static generation
77
export const dynamic = 'force-dynamic';
88

9-
// GET /api/projects/[name]/devlogs/[devlogId] - Get specific devlog entry
9+
// GET /api/projects/[name]/devlogs/[id] - Get specific devlog entry
1010
export async function GET(
1111
request: NextRequest,
1212
{ params }: { params: { name: string; devlogId: string } },
@@ -55,7 +55,7 @@ export async function GET(
5555
}
5656
}
5757

58-
// PUT /api/projects/[name]/devlogs/[devlogId] - Update devlog entry
58+
// PUT /api/projects/[name]/devlogs/[id] - Update devlog entry
5959
export async function PUT(
6060
request: NextRequest,
6161
{ params }: { params: { name: string; devlogId: string } },
@@ -106,7 +106,7 @@ export async function PUT(
106106
}
107107
}
108108

109-
// DELETE /api/projects/[name]/devlogs/[devlogId] - Delete devlog entry
109+
// DELETE /api/projects/[name]/devlogs/[id] - Delete devlog entry
110110
export async function DELETE(
111111
request: NextRequest,
112112
{ params }: { params: { name: string; devlogId: string } },

packages/web/app/lib/api/api-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const RouteParams = {
5353

5454
/**
5555
* Parse project name and devlog ID parameters (name-only routing for projects)
56-
* Usage: /api/projects/[name]/devlogs/[devlogId]
56+
* Usage: /api/projects/[name]/devlogs/[id]
5757
*/
5858
parseProjectNameAndDevlogId(params: { name: string; devlogId: string }) {
5959
try {

packages/web/app/lib/api/devlog-api-client.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
DevlogFilter,
44
DevlogId,
55
DevlogNote,
6+
DevlogNoteCategory,
67
DevlogPriority,
78
DevlogStats,
89
DevlogStatus,
@@ -13,7 +14,6 @@ import type {
1314
TimeSeriesStats,
1415
} from '@codervisor/devlog-core';
1516
import { apiClient } from './api-client';
16-
import { CreateNoteRequest, UpdateNoteRequest } from '@/lib';
1717

1818
export interface CreateDevlogRequest {
1919
title: string;
@@ -40,6 +40,16 @@ export interface BatchUpdateRequest {
4040
tags?: string[];
4141
}
4242

43+
export interface CreateNoteRequest {
44+
content: string;
45+
category?: DevlogNoteCategory;
46+
}
47+
48+
export interface UpdateNoteRequest {
49+
content?: string;
50+
category?: DevlogNoteCategory;
51+
}
52+
4353
export interface BatchNoteRequest {
4454
content: string;
4555
category?: string;
@@ -107,7 +117,10 @@ export class DevlogApiClient {
107117
* Update an existing devlog
108118
*/
109119
async update(devlogId: DevlogId, data: UpdateDevlogRequest): Promise<DevlogEntry> {
110-
return apiClient.put<DevlogEntry>(`/api/projects/${this.projectName}/devlogs/${devlogId}`, data);
120+
return apiClient.put<DevlogEntry>(
121+
`/api/projects/${this.projectName}/devlogs/${devlogId}`,
122+
data,
123+
);
111124
}
112125

113126
/**

packages/web/app/lib/api/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@
55

66
export * from './api-client';
77
export * from './devlog-api-client';
8-
export * from './note-api-client';

packages/web/app/lib/api/note-api-client.ts

Lines changed: 0 additions & 65 deletions
This file was deleted.

packages/web/app/lib/routing/route-params.ts

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -63,46 +63,9 @@ export const RouteParamParsers = {
6363
/**
6464
* Parse project route parameters
6565
* For routes like: /projects/[name]/...
66+
* @deprecated
6667
*/
6768
parseProjectParams(params: { id: string }): ParsedProjectParams {
6869
return parseProjectIdentifier(params.id, 'project identifier');
6970
},
70-
71-
/**
72-
* Parse project + devlog route parameters
73-
* For routes like: /projects/[name]/devlogs/[devlogId]/...
74-
*/
75-
parseDevlogParams(params: { id: string; devlogId: string }): ParsedDevlogParams {
76-
const projectInfo = parseProjectIdentifier(params.id, 'project identifier');
77-
return {
78-
...projectInfo,
79-
devlogId: parseId(params.devlogId, 'devlog ID') as DevlogId,
80-
};
81-
},
82-
83-
/**
84-
* Parse single devlog ID parameter
85-
* For routes like: /devlogs/[name]/...
86-
*/
87-
parseDevlogId(params: { id: string }): { devlogId: DevlogId } {
88-
return {
89-
devlogId: parseId(params.id, 'devlog ID') as DevlogId,
90-
};
91-
},
9271
};
93-
94-
/**
95-
* Hook for parsing route parameters in client components
96-
*/
97-
export function useRouteParams<P extends Record<string, string>, T>(
98-
params: P,
99-
parser: (params: P) => T,
100-
): T {
101-
try {
102-
return parser(params);
103-
} catch (error) {
104-
throw new Error(
105-
`Route parameter error: ${error instanceof Error ? error.message : 'Invalid parameters'}`,
106-
);
107-
}
108-
}

packages/web/app/projects/[name]/ProjectProvider.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ interface ProjectContextValue {
1010

1111
const ProjectContext = createContext<ProjectContextValue | null>(null);
1212

13-
export function ProjectProvider({
14-
children,
15-
project
16-
}: {
13+
export function ProjectProvider({
14+
children,
15+
project,
16+
}: {
1717
children: React.ReactNode;
1818
project: Project;
1919
}) {
@@ -22,11 +22,7 @@ export function ProjectProvider({
2222
projectName: project.name,
2323
};
2424

25-
return (
26-
<ProjectContext.Provider value={value}>
27-
{children}
28-
</ProjectContext.Provider>
29-
);
25+
return <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>;
3026
}
3127

3228
export function useProject(): ProjectContextValue {
@@ -40,4 +36,4 @@ export function useProject(): ProjectContextValue {
4036
export function useProjectName(): string {
4137
const { projectName } = useProject();
4238
return projectName;
43-
}
39+
}

0 commit comments

Comments
 (0)