This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

formatting

+28 -29
+22 -5
docs/shared_types.md
··· 150 150 151 151 export class GetUrlCardsUseCase { 152 152 async execute( 153 - query: GetUrlCardsQuery 154 - ): Promise<Result<GetUrlCardsResponse, ValidationError | AppError.UnexpectedError>> { 153 + query: GetUrlCardsQuery, 154 + ): Promise< 155 + Result<GetUrlCardsResponse, ValidationError | AppError.UnexpectedError> 156 + > { 155 157 // Implementation returns GetUrlCardsResponse type 156 158 return ok({ 157 159 cards: enrichedCards, ··· 204 206 } from '../../shared/api'; 205 207 206 208 export class ApiClient { 207 - async getMyUrlCards(params?: GetMyUrlCardsRequest): Promise<GetUrlCardsResponse> { 209 + async getMyUrlCards( 210 + params?: GetMyUrlCardsRequest, 211 + ): Promise<GetUrlCardsResponse> { 208 212 return this.queryClient.getMyUrlCards(params); 209 213 } 210 214 211 - async addUrlToLibrary(request: AddUrlToLibraryRequest): Promise<AddUrlToLibraryResponse> { 215 + async addUrlToLibrary( 216 + request: AddUrlToLibraryRequest, 217 + ): Promise<AddUrlToLibraryResponse> { 212 218 return this.cardClient.addUrlToLibrary(request); 213 219 } 214 220 } ··· 217 223 ## Migration Strategy 218 224 219 225 ### Phase 1: Setup Infrastructure 226 + 220 227 1. Create `src/shared/api/` directory structure 221 228 2. Move existing webapp types to shared location 222 229 3. Update webapp imports to use shared types 223 230 224 231 ### Phase 2: Backend Integration (Per Endpoint) 232 + 225 233 For each API endpoint: 234 + 226 235 1. **Identify the endpoint** (e.g., `GET /api/cards/my`) 227 236 2. **Update use case** to return shared response type 228 237 3. **Update controller** to use shared types 229 238 4. **Test the endpoint** to ensure types match 230 239 231 240 ### Phase 3: Validation (Optional) 241 + 232 242 Add runtime validation using libraries like Zod: 233 243 234 244 ```typescript ··· 254 264 Here's how a complete request/response flow works: 255 265 256 266 1. **Frontend makes request:** 267 + 257 268 ```typescript 258 269 const response: GetUrlCardsResponse = await apiClient.getMyUrlCards({ 259 270 page: 1, 260 271 limit: 20, 261 272 sortBy: 'updatedAt', 262 - sortOrder: 'desc' 273 + sortOrder: 'desc', 263 274 }); 264 275 ``` 265 276 266 277 2. **Controller receives request:** 278 + 267 279 ```typescript 268 280 // TypeScript ensures the response matches GetUrlCardsResponse 269 281 const result = await this.useCase.execute(query); ··· 271 283 ``` 272 284 273 285 3. **Use case returns typed response:** 286 + 274 287 ```typescript 275 288 // Return type is enforced by TypeScript 276 289 return ok({ ··· 283 296 ## Best Practices 284 297 285 298 ### Type Naming Conventions 299 + 286 300 - **Requests**: `{Action}{Resource}Request` (e.g., `GetUrlCardsRequest`) 287 301 - **Responses**: `{Action}{Resource}Response` (e.g., `GetUrlCardsResponse`) 288 302 - **Common types**: Descriptive names (e.g., `User`, `Pagination`) 289 303 290 304 ### File Organization 305 + 291 306 - Keep related types together in the same file 292 307 - Use barrel exports (`index.ts`) for clean imports 293 308 - Separate common types from endpoint-specific types 294 309 295 310 ### Error Handling 311 + 296 312 - Define error response types consistently 297 313 - Use discriminated unions for different error types 298 314 - Include error codes and messages in shared types 299 315 300 316 ### Versioning 317 + 301 318 - Consider API versioning in type names if needed 302 319 - Use semantic versioning for breaking changes 303 320 - Document breaking changes in migration guides
+1 -5
src/modules/cards/application/useCases/queries/GetCollectionsForUrlUseCase.ts
··· 9 9 import { IProfileService } from '../../../domain/services/IProfileService'; 10 10 import { ICollectionRepository } from '../../../domain/ICollectionRepository'; 11 11 import { CollectionId } from '../../../domain/value-objects/CollectionId'; 12 - import { 13 - CollectionDTO, 14 - PaginationDTO, 15 - CollectionSortingDTO, 16 - } from '../../dtos'; 12 + import { CollectionDTO, PaginationDTO, CollectionSortingDTO } from '../../dtos'; 17 13 18 14 export interface GetCollectionsForUrlQuery { 19 15 url: string;
+1 -5
src/modules/cards/application/useCases/queries/GetCollectionsUseCase.ts
··· 8 8 import { IProfileService } from 'src/modules/cards/domain/services/IProfileService'; 9 9 import { DIDOrHandle } from 'src/modules/atproto/domain/DIDOrHandle'; 10 10 import { IIdentityResolutionService } from 'src/modules/atproto/domain/services/IIdentityResolutionService'; 11 - import { 12 - CollectionDTO, 13 - PaginationDTO, 14 - CollectionSortingDTO, 15 - } from '../../dtos'; 11 + import { CollectionDTO, PaginationDTO, CollectionSortingDTO } from '../../dtos'; 16 12 17 13 export interface GetCollectionsQuery { 18 14 curatorId: string;
+1 -5
src/modules/cards/application/useCases/queries/GetNoteCardsForUrlUseCase.ts
··· 7 7 } from '../../../domain/ICardQueryRepository'; 8 8 import { URL } from '../../../domain/value-objects/URL'; 9 9 import { IProfileService } from '../../../domain/services/IProfileService'; 10 - import { 11 - NoteCardDTO, 12 - PaginationDTO, 13 - CardSortingDTO, 14 - } from '../../dtos'; 10 + import { NoteCardDTO, PaginationDTO, CardSortingDTO } from '../../dtos'; 15 11 16 12 export interface GetNoteCardsForUrlQuery { 17 13 url: string;
+1 -4
src/modules/cards/application/useCases/queries/GetUrlCardViewUseCase.ts
··· 9 9 import { IProfileService } from '../../../domain/services/IProfileService'; 10 10 import { ICollectionRepository } from '../../../domain/ICollectionRepository'; 11 11 import { CollectionId } from '../../../domain/value-objects/CollectionId'; 12 - import { 13 - UserProfileDTO, 14 - CollectionDTO, 15 - } from '../../dtos'; 12 + import { UserProfileDTO, CollectionDTO } from '../../dtos'; 16 13 17 14 export interface GetUrlCardViewQuery { 18 15 cardId: string;
+1 -1
src/webapp/features/cards/components/addCardToModal/AddCardToModal.tsx
··· 30 30 interface Props { 31 31 isOpen: boolean; 32 32 onClose: () => void; 33 - cardContent: UrlCard["cardContent"]; 33 + cardContent: UrlCard['cardContent']; 34 34 cardId: string; 35 35 } 36 36
+1 -4
src/webapp/features/cards/components/addCardToModal/CardToBeAddedPreview.tsx
··· 12 12 Tooltip, 13 13 } from '@mantine/core'; 14 14 import Link from 'next/link'; 15 - import { 16 - GetUrlStatusForMyLibraryResponse, 17 - UrlCard, 18 - } from '@/api-client/types'; 15 + import { GetUrlStatusForMyLibraryResponse, UrlCard } from '@/api-client/types'; 19 16 import { BiCollection } from 'react-icons/bi'; 20 17 import { LuLibrary } from 'react-icons/lu'; 21 18 import { getDomain } from '@/lib/utils/link';