Fuscorrespondence General Tech Design
Design Documents
Last updated August 2, 2025
Fuscorrespondence General Tech Design
Core Features Implementation Status
Feature | Description | Implementation Status & Details |
---|---|---|
Login | Users must be authenticated through fuscauth to use this app. | ✅ Implemented - JWT auth middleware with Bearer token validation |
Mailbox setup | Users must provide their location while using the app and define a FuscAddress | ✅ Implemented - Profile page with location detection, guided onboarding with MailboxSetupPrompt component |
Letter writing | User can write letters in a calm focused area with auto-save functionality | ✅ Implemented - Compose page with rich text editor, auto-save every 3 seconds, draft management |
Letter sending | Users should manually enter the FuscAddress of another user to send a letter | ✅ Implemented - Real-time address validation, recipient FuscAddress input with feedback |
Letter status | Letters have clear status tracking throughout their lifecycle | ✅ Implemented - Simplified system: Draft/Sent + isRead boolean (simplified from 4-state for better UX) |
Notifications | Users see visual indicators when there are unread messages | ✅ Implemented - Mailbox emoji (📪) indicator, unread letter styling in mailbox view |
Delivery tracking | Users can see the delivery status of letters they send | ✅ Implemented - SentLetters page with status tracking, read/unread indicators |
Responsive design | App works seamlessly across desktop and mobile devices | ✅ Implemented - Mobile-first design with animated navigation, touch-friendly interactions |
Onboarding | New users are guided through setup before accessing core features | ✅ Implemented - MailboxSetupPrompt component appears contextually on main pages until mailbox is configured |
Architecture Overview
[React Frontend] → [API Gateway → Lambda Backend] → [DynamoDB]
↑
[Fuscauth Service]
Backend Implementation
Technology Stack
- Framework: Node.js + Express + TypeScript
- Deployment: AWS Lambda with Serverless Framework
- Database: DynamoDB (reusing existing monotable structure)
- Authentication: JWT middleware integrated with fuscauth
- API Gateway: AWS API Gateway for HTTP routing
Base URL
https://6nnj8no7u0.execute-api.us-east-1.amazonaws.com/dev/fuscorrespondence
Implemented API Endpoints
Mailbox Management
POST /mailbox
- Create or update user mailbox with FuscAddress and locationGET /mailbox
- Get user's mailbox information
Letter Operations
POST /letters
- Create a draft letterPATCH /letters/{id}
- Update draft letter contentPOST /letters/{id}/send
- Send a letter (converts draft to sent)GET /letters
- Get user's letters with filtering by status (Draft/Sent) and direction (sent/received)GET /letters/{id}
- Get specific letter details
Address Validation
POST /address/validate
- Validate if a FuscAddress exists in the system
Data Models (Updated)
Letter Model (Simplified for Better UX)
typescript
interface Letter {
pk: string // LETTER#{letterId}
senderUserId: string
senderMailboxId: string
recipientMailboxId: string
status: "Draft" | "Sent" // Simplified from 4-state system
isRead: boolean // Simple read tracking
content: string
recipientName?: string
senderName?: string
recipientFuscaddress?: string
senderFuscaddress?: string
sentDate?: string // When letter was sent
createdAt: string
updatedAt: string
}
Mailbox Model
typescript
interface Mailbox {
pk: string // USER#{userId}
sk: string // MAILBOX#{mailboxId}
fuscaddress: string // User's unique FuscAddress
location: {
latitude: number
longitude: number
}
createdAt: string
updatedAt: string
}
Database Design
DynamoDB Monotable Structure
- Table:
fuscapp-monotable-dev
(reusing existing infrastructure) - Partition Strategy: Entity-based partitioning
- Entities:
- Mailbox:
PK: USER#{userId}
,SK: MAILBOX#{mailboxId}
- Letter:
PK: LETTER#{letterId}
,SK: LETTER#{letterId}
- Mailbox:
Query Patterns
- Get user's mailbox:
PK = USER#{userId} AND begins_with(SK, 'MAILBOX#')
- Get user's letters: Filter by senderUserId or recipientMailboxId
- Validate address: Scan for fuscaddress (could be optimized with GSI)
Business Logic Simplifications
Status Management (Simplified)
Previous: Draft → InTransit → Delivered → Read (4 states)
Current: Draft → Sent + isRead boolean (2 states + boolean)
Rationale:
- Reduces complexity in UI state management
- Eliminates need for background job processing for status transitions
- Still provides essential tracking (sent/not sent, read/unread)
- Simpler to understand and debug
Distance-Based Delivery (Simplified)
Previous: Complex distance calculation with delivery delays
Current: Immediate delivery upon sending
Rationale:
- Core value is in thoughtful composition, not artificial delays
- Simplifies backend processing and reduces infrastructure complexity
- Can be re-implemented later if needed
Frontend Implementation
Technology Stack
- Framework: React 18 with TypeScript
- Build Tool: Vite
- UI Library: shadcn/ui components + Radix UI primitives
- Styling: Tailwind CSS with custom amber theme
- State Management: TanStack Query (React Query) for server state
- Routing: React Router v6
- Authentication: JWT tokens with localStorage persistence
- Form Handling: React Hook Form with validation
Repository Structure (Current)
web/
├── public/
│ ├── index.html
│ └── fuscorrespondence_logo_transparent.png
├── src/
│ ├── components/
│ │ ├── ui/ # shadcn/ui base components
│ │ │ ├── button.tsx
│ │ │ ├── input.tsx
│ │ │ ├── textarea.tsx
│ │ │ └── toaster.tsx
│ │ ├── layout/
│ │ │ └── Navigation.tsx # Main nav with mobile animations
│ │ ├── letters/
│ │ │ └── LetterCard.tsx # Letter preview with content truncation
│ │ └── onboarding/
│ │ └── MailboxSetupPrompt.tsx # Guided onboarding component
│ ├── pages/
│ │ ├── Mailbox.tsx # Received letters with unread indicators
│ │ ├── Compose.tsx # Letter writing with auto-save
│ │ ├── Drafts.tsx # Draft management and editing
│ │ ├── SentLetters.tsx # Sent letters with read status
│ │ ├── Profile.tsx # Mailbox setup and management
│ │ ├── LetterReading.tsx # Individual letter view
│ │ └── NotFound.tsx # 404 error handling
│ ├── hooks/
│ │ └── useApi.ts # Custom API integration hooks
│ ├── lib/
│ │ ├── api.ts # API client with auth
│ │ ├── auth.ts # Authentication utilities
│ │ ├── types.ts # TypeScript definitions
│ │ └── utils.ts # Helper functions
│ ├── App.tsx # Main app with routing
│ └── main.tsx # Entry point
├── components.json # shadcn/ui configuration
├── tailwind.config.ts # Tailwind configuration
├── vite.config.ts # Vite build configuration
└── package.json
Key Frontend Features
Onboarding Experience
- MailboxSetupPrompt: Welcoming component that appears on main pages when no mailbox is configured
- Contextual guidance: Setup prompt integrates naturally into existing pages
- Visual consistency: Uses amber theme with MapPin icon for cohesive branding
Mobile-First Design
- Animated Navigation: Smooth slide-in/slide-out transitions for mobile navbar
- Touch Optimization: All interactions optimized for touch devices
- Responsive Layout: Seamless adaptation across all screen sizes
User Experience Enhancements
- Auto-save: Draft letters save automatically every few seconds
- Content Preview: Smart truncation of letter content in list views
- Empty States: Meaningful empty state messages with appropriate emojis
- Fixed Scrolling: Pages only scroll when content exceeds viewport height
- Cache Management: Intelligent data caching with proper invalidation
Letter Management
- Rich Text Editor: Formatting controls for letter composition
- Real-time Validation: Address validation with immediate feedback
- Status Tracking: Clear visual indicators for draft/sent/read status
- Bulk Operations: Efficient management of multiple drafts
State Management Strategy
TanStack Query Implementation
typescript
// Example: Custom hook for letter operations
export const useLetters = (filter?: "sent" | "received") => {
return useQuery({
queryKey: ["letters", filter],
queryFn: () => api.getLetters(filter),
staleTime: 5 * 60 * 1000, // 5 minutes
})
}
export const useSendLetter = () => {
const queryClient = useQueryClient()
return useMutation({
mutationFn: ({ letterId, recipientFuscaddress }: SendLetterRequest) =>
api.sendLetter(letterId, recipientFuscaddress),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["letters"] })
queryClient.invalidateQueries({ queryKey: ["drafts"] })
},
})
}
Benefits
- Automatic caching with intelligent invalidation strategies
- Background refetching keeps data fresh
- Optimistic updates for immediate UI feedback
- Error handling with automatic retries
- Loading states handled automatically
Authentication Flow
- Initial Access: User navigates to app
- Auth Check: App checks for valid JWT in localStorage
- Redirect to Fuscauth: If no valid token, redirect to authentication service
- Token Handling: On successful auth, token is stored and user returns to app
- API Requests: All subsequent requests include Bearer token in headers
- Token Refresh: Automatic handling of token expiration (when implemented)
API Integration
Centralized API Client
typescript
class FuscorrespondenceAPI {
private baseURL =
"https://6nnj8no7u0.execute-api.us-east-1.amazonaws.com/dev/fuscorrespondence"
private async request<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const token = getAuthToken()
const response = await fetch(`${this.baseURL}${endpoint}`, {
...options,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...options.headers,
},
})
if (!response.ok) {
throw new Error(`API Error: ${response.statusText}`)
}
return response.json()
}
// Letter operations
async createDraft(content: string): Promise<Letter> {
/* ... */
}
async sendLetter(
letterId: string,
recipientAddress: string
): Promise<Letter> {
/* ... */
}
async getLetters(filter?: string): Promise<Letter[]> {
/* ... */
}
// Mailbox operations
async createMailbox(data: CreateMailboxRequest): Promise<Mailbox> {
/* ... */
}
async getMailbox(): Promise<Mailbox> {
/* ... */
}
// Address validation
async validateAddress(address: string): Promise<{ valid: boolean }> {
/* ... */
}
}
Backend Repository Structure (Implemented)
api/
├── src/
│ ├── controllers/
│ │ ├── mailboxController.ts # Mailbox CRUD operations
│ │ ├── letterController.ts # Letter management and sending
│ │ └── addressController.ts # Address validation
│ ├── routes/
│ │ ├── mailboxRoutes.ts # Mailbox API routes
│ │ ├── letterRoutes.ts # Letter API routes
│ │ └── addressRoutes.ts # Address validation routes
│ ├── middlewares/
│ │ ├── authMiddleware.ts # JWT authentication
│ │ └── errorHandler.ts # Global error handling
│ ├── services/
│ │ └── dbService.ts # Database operations and business logic
│ ├── utils/
│ │ ├── responseFormatter.ts # Consistent API response formatting
│ │ └── errorHandler.ts # Error handling utilities
│ ├── types/
│ │ └── express.d.ts # Express type extensions
│ ├── app.ts # Express app configuration
│ └── lambdaHandler.ts # AWS Lambda entry point
├── package.json
├── serverless.yml # Serverless Framework configuration
├── tsconfig.json # TypeScript configuration
└── README.md
Key Backend Features
Authentication Middleware
- JWT token validation on all protected routes
- Integration with existing fuscauth service
- User context injection into request objects
Error Handling
- Consistent error response formatting
- Proper HTTP status codes
- Detailed error logging for debugging
Database Operations
- Efficient DynamoDB queries using monotable pattern
- Proper data validation and sanitization
- Transaction support for complex operations
Deployment & Infrastructure
Backend Deployment
- AWS Lambda: Serverless compute with automatic scaling
- API Gateway: HTTP API with CORS configuration
- DynamoDB: NoSQL database with on-demand pricing
- CloudWatch: Automatic logging and monitoring
Frontend Deployment
- Static Assets: Optimized build with Vite
- CDN Ready: Assets optimized for CDN distribution
- Environment Configuration: Support for multiple deployment environments
Development Workflow
- Local Development: Backend runs locally with hot reload
- Type Safety: Shared types between frontend and backend
- Testing: Unit and integration test support (to be implemented)
Performance Considerations
Frontend Optimizations
- Code Splitting: Lazy loading of routes and components
- Bundle Optimization: Tree shaking and minification with Vite
- Caching Strategy: Aggressive caching with smart invalidation
- Image Optimization: Optimized assets and lazy loading
Backend Optimizations
- Cold Start Mitigation: Optimized Lambda bundle size
- Database Efficiency: Minimal queries with proper indexing
- Response Caching: Appropriate cache headers for static data
Security Considerations
Authentication & Authorization
- JWT Validation: Proper token verification and expiration handling
- CORS Configuration: Restricted to allowed origins
- Input Validation: Server-side validation for all user inputs
Data Protection
- User Isolation: Users can only access their own data
- Secure Communication: HTTPS enforced for all communications
- Token Storage: Secure token handling in browser localStorage
Future Technical Enhancements
Performance
- Background Jobs: Implement queue system for heavy operations
- Database Optimization: Add Global Secondary Indexes for common queries
- Caching Layer: Redis for frequently accessed data
Features
- Real-time Updates: WebSocket support for live letter status updates
- File Attachments: S3 integration for letter attachments
- Search Functionality: ElasticSearch for full-text letter search
- Analytics: User behavior tracking and app metrics
Infrastructure
- Multi-region: Deploy across multiple AWS regions
- Monitoring: Enhanced observability with distributed tracing
- CI/CD: Automated testing and deployment pipelines
Last Updated: January 2025
Status: Core features implemented and deployed